二叉树删除节点
二叉树—删除节点
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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端