二叉树删除节点

二叉树—删除节点

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 }

 

posted @ 2022-04-02 20:44  doremi429  阅读(1131)  评论(0编辑  收藏  举报