二叉樹刪除節點


二叉樹—刪除節點

1)刪除節點是葉子節點,刪除該節點

2)刪除節點是非葉子節點,則刪除該子樹

思路:  

  1、考慮若樹是空樹root,如果只有一個root節點,則等價將二叉樹置空

  2、因二叉樹是單向的,所以判斷當前節點的子節點是否需要刪除,而不能判斷當前這個節點是不是需要刪除節點

  3、如果當前節點的左子節點不為空,並且左子節點就是要刪除節點,就將this.left =null;

並且就返回(結束遞歸刪除)

  4、如果當前節點的右子節點不為空,並且右子節點就是要刪除節點,就將this.right =null;

 並且就返回(結束遞歸刪除)

  5、若第2和第3步沒有刪除節點,需要向左子樹進行遞歸刪除

  6、若第4步也沒有刪除節點,向右子樹進行遞歸刪除

  

  1 public class BinaryTreeDemo {
  2 
  3     public static int PRECOUNT = 0;
  4     public static int INFIXCOUNT = 0;
  5     public static int POSTCOUNT = 0;
  6     public static void main(String[] args) {
  7         //先需要創建一棵二叉樹
  8         BinaryTree binaryTree = new BinaryTree();
  9         EmpNode root = new EmpNode(1, "aa");
 10         EmpNode emp2 = new EmpNode(2, "bb");
 11         EmpNode emp3 = new EmpNode(3, "cc");
 12         EmpNode emp4 = new EmpNode(4, "dd");
 13         EmpNode emp5 = new EmpNode(5, "ee");
 14 
 15         //手動創建二叉樹,后面學習遞歸的方式創建二叉樹
 16         root.setLeft(emp2);
 17         root.setRight(emp3);
 18         emp3.setRight(emp4);
 19         emp3.setLeft(emp5);
 20 
 21         //測試
 22         System.out.println("前序遍歷");
 23         binaryTree.setRoot(root);
 24         binaryTree.preOrder();
 25 
 26         System.out.println("中序遍歷");
 27         binaryTree.setRoot(root);
 28         binaryTree.infixOrder();
 29 
 30 
 31         System.out.println("后序遍歷");
 32         binaryTree.setRoot(root);
 33         binaryTree.postOrder();
 34 
 35         //前序查找
 36         //前序查找次數
 37         System.out.println("前序查找方式");
 38         EmpNode resNode = binaryTree.preOrderSearch(5);
 39         if (resNode != null){
 40             System.out.printf("找到,信息為no=%d name=%s 查詢次數為%s",resNode.getNo(),resNode.getName(),PRECOUNT);
 41 
 42         }else {
 43             System.out.printf("沒找到 no=%d",5);
 44         }
 45 
 46         System.out.println();
 47 
 48         //中序查找
 49         //中序查找次數
 50         System.out.println("中序查找方式");
 51         EmpNode resNode1 = binaryTree.infixOrderSearch(5);
 52         if (resNode1 != null){
 53             System.out.printf("找到,信息為no=%d name=%s 查詢次數為%s",resNode1.getNo(),resNode1.getName(),INFIXCOUNT);
 54 
 55         }else {
 56             System.out.printf("沒找到 no=%d",5);
 57         }
 58 
 59         System.out.println();
 60 
 61         //后序查找
 62         //后序查找次數
 63         System.out.println("后序查找方式");
 64         EmpNode resNode2 = binaryTree.postOrderSearch(5);
 65         if (resNode1 != null){
 66             System.out.printf("找到,信息為no=%d name=%s 查詢次數為%s",resNode2.getNo(),resNode2.getName(),POSTCOUNT);
 67 
 68         }else {
 69             System.out.printf("沒找到 no=%d",5);
 70         }
 71 
 72 
 73 
 74 
 75     }
 76 
 77 }
 78 
 79 //2.定義一個BinaryTree
 80 class BinaryTree {
 81     private EmpNode root;
 82 
 83     public void setRoot(EmpNode root) {
 84         this.root = root;
 85     }
 86 
 87     //前序遍歷
 88     public void preOrder() {
 89         if (this.root != null) {
 90             this.root.preOrder();
 91         } else {
 92             System.out.println("二叉樹為空,無法遍歷");
 93         }
 94     }
 95 
 96     //中序遍歷
 97     public void infixOrder() {
 98         if (this.root != null) {
 99             this.root.infixOrder();
100         } else {
101             System.out.println("二叉樹為空,無法遍歷");
102         }
103     }
104 
105     //后序遍歷
106     public void postOrder() {
107         if (this.root != null) {
108             this.root.postOrder();
109         } else {
110             System.out.println("二叉樹為空,無法遍歷");
111         }
112     }
113 
114     //前序查找
115     public EmpNode preOrderSearch(int no){
116         if (root != null){
117             return root.preOrderSearch(no);
118         }else {
119             return null;
120         }
121     }
122 
123     //中序查找
124     public EmpNode infixOrderSearch(int no){
125         if (root != null){
126             return root.infixOrderSearch(no);
127         }else {
128             return null;
129         }
130     }
131     //后序查找
132     public EmpNode postOrderSearch(int no){
133         if (root != null){
134             return root.postOrderSearch(no);
135         }else {
136             return null;
137         }
138     }
139 
140     //刪除節點
141     public void delNode(int no){
142         if (root != null){
143             //如果只有一個root節點,需要立即判斷是不是要刪除節點
144             if (root.getNo() == no){
145                 root = null;
146             }else{
147                 root.delNode(no);
148             }
149 
150         }else {
151             System.out.println("空樹,不能刪除");
152         }
153     }
154 }
155 
156 //1.先創建HeroNode
157 class EmpNode {
158     private int no;
159     private String name;
160     private EmpNode left;//默認為null
161     private EmpNode right;//默認為null
162 
163     public EmpNode(int no, String name) {
164         this.no = no;
165         this.name = name;
166     }
167 
168     public int getNo() {
169         return no;
170     }
171 
172     public void setNo(int no) {
173         this.no = no;
174     }
175 
176     public String getName() {
177         return name;
178     }
179 
180     public void setName(String name) {
181         this.name = name;
182     }
183 
184     public EmpNode getLeft() {
185         return left;
186     }
187 
188     public void setLeft(EmpNode left) {
189         this.left = left;
190     }
191 
192     public EmpNode getRight() {
193         return right;
194     }
195 
196     public void setRight(EmpNode right) {
197         this.right = right;
198     }
199 
200     @Override
201     public String toString() {
202         return "EmpNode{" +
203                 "no=" + no +
204                 ", name='" + name + '\'' +
205                 '}';
206     }
207 
208     //遞歸刪除節點
209     //1.若刪除的節點是葉子節點,則刪除該節點
210     //2.若刪除的節點是非葉子節點,則刪除該子樹
211     public void delNode(int no){
212         //思路
213         if (this.left != null && this.left.no == no){
214             this.left = null;
215             return;
216         }
217         if (this.right != null && this.right.no == no){
218             this.right = null;
219             return;
220         }
221 
222         if (this.left != null){
223             this.left.delNode(no);
224             //return;寫了return有可能下面向右不執行了
225         }
226         if (this.right != null){
227             this.right.delNode(no);
228         }
229     }
230 
231     //編寫前序遍歷方法
232 
233     public void preOrder() {
234         System.out.println(this);//先輸出父節點
235         //遞歸向左子樹前序遍歷
236         if (this.left != null) {
237             this.left.preOrder();
238         }
239         //遞歸向右子樹前序遍歷
240         if (this.right != null) {
241             this.right.preOrder();
242         }
243 
244     }
245 
246     //編寫中序遍歷方法
247     public void infixOrder() {
248         //遞歸向左子樹中序遍歷
249         if (this.left != null) {
250             this.left.infixOrder();//2,1,3,4
251         }
252         //輸出父節點
253         System.out.println(this);
254         //遞歸向右子樹中序遍歷
255         if (this.right != null) {
256             this.right.infixOrder();
257         }
258     }
259 
260     //編寫后序遍歷方法
261     public void postOrder() {
262         if (this.left != null) {
263             this.left.postOrder();
264         }
265         if (this.right != null) {
266             this.right.postOrder();
267         }
268         System.out.println(this);
269     }
270 
271     /**
272      * @param no 查找no
273      * @return 若找到就返回該Node,若沒找到返回Null
274      */
275     //前序遍歷查找
276     public EmpNode preOrderSearch(int no) {
277         BinaryTreeDemo.PRECOUNT++;
278         //System.out.println("進入前序查找");
279 
280         //比較當前節點是不是
281         if (this.no == no) {
282             return this;
283         }
284         //判斷當前節點的左子節點是否為空,若不為空,則遞歸前序查找
285         //若左遞歸前序查找,找到節點,則返回
286 
287         EmpNode resNode = null;
288         if (this.left != null) {
289             resNode = this.left.preOrderSearch(no);
290         }
291         if (resNode != null) {
292             return resNode;
293         }
294 
295         //左遞歸前序查找,找到節點,則返回,否繼續判斷
296         //當前的結點的右子節點是否為空,若為空,則繼續向右遞歸前序查找
297         if (this.right != null) {
298             resNode = this.right.preOrderSearch(no);
299         }
300         return resNode;
301 
302     }
303 
304     //中序遍歷查找
305     public EmpNode infixOrderSearch(int no) {
306 
307         //判斷當前節點的左子節點是否為空,若不為空,則遞歸中序查找
308         EmpNode resNode = null;
309         if (this.left != null) {
310             resNode = this.left.infixOrderSearch(no);
311         }
312         if (resNode != null) {
313             return resNode;
314         }
315         BinaryTreeDemo.INFIXCOUNT++;
316         //若找到,則返回,若沒找到,就和當前節點比較,若是則返回
317         if (this.no == no) {
318             return this;
319         }
320         //否則繼續進行右遞歸的中序查找
321         if (this.right != null) {
322             resNode = this.right.infixOrderSearch(no);
323         }
324         return resNode;
325 
326     }
327 
328     //后序遍歷查找
329     public EmpNode postOrderSearch(int no) {
330 
331 
332         //判斷當前節點的左子節點是否為空,若不為空,則繼續遞歸后序查找
333         EmpNode resNode = null;
334         if (this.left != null) {
335             resNode = this.left.postOrderSearch(no);
336         }
337         if (resNode != null) {//說明左子樹找到
338             return resNode;
339         }
340         //若左子樹沒找到,則向右子樹遞歸進行后序遍歷查找
341         if (this.right != null) {
342             resNode = this.right.postOrderSearch(no);
343         }
344         if (resNode != null) {
345             return resNode;
346         }
347         //若左右子樹都沒找到,就比較當前節點是不是
348         BinaryTreeDemo.POSTCOUNT++;
349         if (this.no == no) {
350             return this;
351         }
352         return resNode;
353     }
354 
355 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM