日常学习随笔-用链表的形式实现普通二叉树的删除(源码+说明)(补充篇)
一、二叉树删除的三种情况
删除二叉树查找树的节点吧。总共有三种情况
1.被删除的节点是叶子节点,这时候只要把这个节点删除,再把指向这个节点的父节点指针置为空就行
2.被删除的节点有左子树,或者有右子树,而且只有其中一个,那么只要把当前删除节点的父节点指向被删除节点的左子树或者右子树就行。
3.被删除的节点既有左子树而且又有右子树,这时候需要把左子树的最右边的节点或者右子树最左边的节点提到被删除节点的位置,为什么要这样呢,根据二叉查找树的性质,父节点的指针一定比所有左子树的节点值大而且比右子树的节点的值小,为了删除父节点不破坏二叉查找树的平衡性,应当把左子树最大的节点或者右子树最小的节点放在父节点的位置,这样的话才能维护二叉查找树的平衡性。(我是找的左子树的最大节点)
或者
二、源码案例:
完整的二叉树类:
二叉树完整自定义源码:
1 package com.xfwl.algorithmAnalysis.trees; 2 /** 3 * 二叉树结构分析 4 * @function 日常学习测试 5 * @author 小风微凉 6 * @time 2018-5-20 下午12:28:50 7 */ 8 public class MyTreeDefin<T extends Comparable<? super T>>{ 9 /** 10 * 每棵树都有一个根节点 11 */ 12 private BinaryNode<T> root; 13 /** 14 * 整棵树的节点个数 15 */ 16 private int nodeCount; 17 /** 18 * 二叉树构造器 19 */ 20 public MyTreeDefin(){ 21 this.reset(); 22 } 23 /** 24 * 重置整棵树的结构 25 */ 26 private void reset(){ 27 //二叉树的根节点初始化 28 root=null; 29 //二叉树的节点总数:归0 30 this.nodeCount=0; 31 } 32 /** 33 * 清空整棵二叉树 34 * @return 35 */ 36 public boolean makeEmpty(){ 37 this.reset(); 38 return this.isEmpty(); 39 } 40 /** 41 * 获取树的节点个数 42 * @return 43 */ 44 public int getSize(){ 45 return this.nodeCount; 46 } 47 /** 48 * 判断整棵树是否为空树 49 * @return 50 */ 51 public boolean isEmpty(){ 52 return this.nodeCount==0?true:false; 53 } 54 /** 55 * 判断二叉树中指定节点后面是否包含指定数据 56 * @param target 检索数据target 57 * @param node 指定的节点(包含当前节点) 58 * @return 59 */ 60 public boolean contains(T target,BinaryNode<T> node){ 61 //判空检查 62 if(node==null){ 63 return false; 64 } 65 //先和当前节点的数据比较 66 int compareResult=target.compareTo(node.elem); 67 if(compareResult>0){//进入右子树中继续判断 68 return contains(target,node.right); 69 }else if(compareResult<0){//进入左子树中继续判断 70 return contains(target,node.left); 71 }else{//相等 72 return true; 73 } 74 } 75 /** 76 * 从根节点开始查找整棵树是否包含指定的数据 77 * @param target 检索数据target 78 * @return 79 */ 80 public boolean contains(T target){ 81 return this.contains(target, this.root); 82 } 83 /** 84 * 查找整棵树中的最小数据 85 * 左子树最后一个节点数据 86 * @return 87 */ 88 public T findMin(){ 89 return this.findMin(this.root).elem; 90 } 91 /** 92 * 查找指定树节点下面的最小节点[查找指定节点后面的最小节点] 93 * @param node 指定的节点 94 * @return 95 */ 96 public BinaryNode<T> findMin(BinaryNode<T> node){ 97 //如果节点为空 98 if(node==null){ 99 return null; 100 }else if(node.left==null){//递归基准情况 101 return node; 102 }else{//递归流程 103 return findMin(node.left); 104 } 105 } 106 /** 107 * 查找指定树节点下面的最大节点[最大的数据在右子树的最深叶子节点] 108 * @param node 指定的查找起点节点 109 * @return 110 */ 111 public BinaryNode<T> findMax(BinaryNode<T> node){ 112 //如果节点为空 113 if(node==null){ 114 return null; 115 }else if(node.right==null){//递归基准情况 116 return node; 117 }else{//递归流程 118 return findMax(node.right); 119 } 120 } 121 /** 122 * 查找整棵树中的最大数据 123 * @return 124 */ 125 public T findMax(){ 126 return this.findMax(this.root).elem; 127 } 128 /** 129 * 为二叉树添加新的节点(对外) 130 * @param data 要添加的数据 131 * @return 132 */ 133 public BinaryNode<T> add(T data){ 134 if(this.isEmpty()){ 135 this.nodeCount++; 136 this.root=new BinaryNode<>(data,null,null); 137 return this.root; 138 }else{ 139 this.nodeCount++; 140 return this.add(data, this.root); 141 } 142 } 143 /** 144 * 为二叉树添加新的节点(对内) 145 * @param data 要添加的数据 146 * @param curNode 要添加的节点(递归比较) 147 */ 148 private BinaryNode<T> add(T data,BinaryNode<T> curNode){ 149 //如果节点不存在:递归基准情况 150 if(curNode==null){ 151 return new BinaryNode<>(data,null,null); 152 } 153 //按照:左>根>右 的大小顺序插入二叉树中 154 //比较起点:先和根节点数据比较 155 int compareResult=data.compareTo(curNode.elem); 156 if(compareResult<0){//走左子树 157 System.out.println("左<--"); 158 curNode.left=this.add(data,curNode.left); 159 }else if(compareResult>0){//走右子树 160 System.out.println("-->右"); 161 curNode.right=this.add(data,curNode.right); 162 }else{//如果添加的节点数据和当前比较的根节点相同 163 //不做任何处理,可在此继续扩展 164 } 165 //返回的是根节点 166 return curNode; 167 } 168 /** 169 * 非递归添加树节点 170 * @param data 节点数据 171 * @return 172 */ 173 public void push(T data){ 174 if(this.isEmpty()){//空树结构 175 this.nodeCount++; 176 this.root=new BinaryNode<>(data,null,null); 177 }else{//至少含有一个根节点 178 BinaryNode<T> tmpNode =this.root; 179 System.out.println("--------------------根节点数据:"+tmpNode.elem+",--------------------"); 180 while(true){ 181 System.out.println("while----:tmpNode.elem="+tmpNode.elem+",data="+data); 182 int compareResult=data.compareTo(tmpNode.elem); 183 if(compareResult<0){//走左子树 184 System.out.println("左<--"); 185 if(tmpNode.left==null){ 186 tmpNode.left=new BinaryNode<>(data,null,null); 187 break; 188 } 189 tmpNode=tmpNode.left; 190 }else if(compareResult>0){//走右子树 191 System.out.println("-->右"); 192 if(tmpNode.right==null){ 193 tmpNode.right=new BinaryNode<>(data,null,null); 194 break; 195 } 196 tmpNode=tmpNode.right; 197 }else{//替换当前节点数据(压入相同数据,没改变) 198 //也即不做处理 199 break; 200 } 201 } 202 this.nodeCount++; 203 } 204 } 205 /** 206 * 移除二叉树中根节点后面的指定数据(所在的节点) 207 * @param data 指定的数据 208 */ 209 public boolean remove(T data){ 210 boolean ret=false; 211 //要删除的数据所在的结点存在 212 if(!this.contains(data)){ 213 return ret; 214 } 215 //要删除的节点 216 BinaryNode<T> target=this.getNode(data, this.root); 217 if(target!=null){ 218 //要删除的节点的上一级节点 219 BinaryNode<T> parNode= this.getPrevNode(data); 220 System.out.println("parNode==null:"+(parNode==null)); 221 //(1)当前节点为叶子节点 222 if(target.left==null && target.right==null){ 223 target=null; 224 if(parNode!=null){ 225 if(data.compareTo(parNode.elem)>0){//右子树 226 parNode.right=null; 227 }else if(data.compareTo(parNode.elem)<0){//左子树 228 parNode.left=null; 229 } 230 }else{//删除的是根节点 231 this.root=null; 232 } 233 ret=true; 234 } 235 //(2)只有一个子树(左或者右) 236 else if(target.left!=null && target.right==null){ 237 target=target.left; 238 if(parNode!=null){ 239 if(data.compareTo(parNode.elem)>0){//右子树 240 parNode.right=target; 241 }else if(data.compareTo(parNode.elem)<0){//左子树 242 parNode.left=target; 243 } 244 }else{//删除的是根节点 245 this.root=this.root.left; 246 } 247 ret=true; 248 }else if(target.left==null && target.right!=null){ 249 target=target.right; 250 if(parNode!=null){ 251 if(data.compareTo(parNode.elem)>0){//右子树 252 parNode.right=target; 253 }else if(data.compareTo(parNode.elem)<0){//左子树 254 parNode.left=target; 255 } 256 }else{//删除的是根节点 257 this.root=this.root.right; 258 } 259 ret=true; 260 } 261 //(3)左右子树都有 262 /** 263 * 最麻烦的一种删除方式: 264 * [1]找到要删除节点的父节点,判断当前节点是在父节点的左子树还是右子树。 265 * [2]找到当前删除节点的左子树的最大节点,替换当前删除节点。 266 * [3]当前删除节点的左子树的最大节点的父节点(针对这个节点的指向清空) 267 * [4]重新设置新结点的左右子树的指向 268 */ 269 else if(target.left!=null && target.right!=null){ 270 //1.取左子树的最大数据节点 271 BinaryNode<T> lmaxNode=this.findMax(target.left); 272 if(parNode!=null){//删除的非根节点 273 if(data.compareTo(parNode.elem)>0){//右子树 274 //2.左子树最大数据节点的上级节点 275 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 276 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 277 if(lmaxNode.left!=null){ 278 maxParNode.right=lmaxNode.left; 279 }else{ 280 maxParNode.right=null; 281 } 282 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 283 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 284 if(maxParNode.elem.equals(target.elem)){ 285 maxParNode.left=lmaxNode.left; 286 }else{ 287 maxParNode.left=null; 288 } 289 } 290 //3.替换当前删除节点 291 lmaxNode.left=target.left; 292 lmaxNode.right=target.right; 293 parNode.right=lmaxNode; 294 }else if(data.compareTo(parNode.elem)<0){//左子树 295 //2.左子树最大数据节点的上级节点 296 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 297 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 298 if(lmaxNode.left!=null){ 299 maxParNode.right=lmaxNode.left; 300 }else{ 301 maxParNode.right=null; 302 } 303 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 304 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 305 if(maxParNode.elem.equals(target.elem)){ 306 maxParNode.left=lmaxNode.left; 307 }else{ 308 maxParNode.left=null; 309 } 310 } 311 //3.替换当前删除节点 312 lmaxNode.left=target.left; 313 lmaxNode.right=target.right; 314 parNode.left=lmaxNode; 315 } 316 }else{//删除的是根节点 317 //2.左子树最大数据节点的上级节点 318 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 319 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 320 if(lmaxNode.left!=null){ 321 maxParNode.right=lmaxNode.left; 322 }else{ 323 maxParNode.right=null; 324 } 325 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 326 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 327 if(maxParNode.elem.equals(target.elem)){ 328 maxParNode.left=lmaxNode.left; 329 }else{ 330 maxParNode.left=null; 331 } 332 } 333 //3.替换当前删除节点 334 lmaxNode.left=target.left; 335 lmaxNode.right=target.right; 336 this.root=lmaxNode; 337 } 338 ret=true; 339 } 340 } 341 this.nodeCount=(ret==true?--this.nodeCount:this.nodeCount); 342 //找到要删除的节点 343 return ret; 344 } 345 public T getPrevNodeElem(T data){ 346 return this.getPrevNode(data).getElem(); 347 } 348 /** 349 * 根据节点数据找到对应的节点的父节点 350 * @param data 节点数据 351 * @return 352 */ 353 public BinaryNode<T> getPrevNode(T data){ 354 if(this.isEmpty()){//空树 355 return null; 356 } 357 if(data.equals(root.getElem())){ 358 return null; 359 } 360 BinaryNode<T> parNode=this.root;//父节点 361 BinaryNode<T> curNode=this.root;//当前节点 362 while(true){ 363 int compareResult=data.compareTo(curNode.elem); 364 if(compareResult>0){//进入右子树中继续判断 365 /*parNode.elem=curNode.elem; 366 parNode.left=curNode.left; 367 parNode.right=curNode.right;*/ 368 parNode=curNode; 369 curNode=curNode.right; 370 }else if(compareResult<0){//进入左子树中继续判断 371 /*parNode.elem=curNode.elem; 372 parNode.left=curNode.left; 373 parNode.right=curNode.right;*/ 374 parNode=curNode; 375 376 curNode=curNode.left; 377 }else{//相等 378 break; 379 } 380 } 381 return parNode; 382 } 383 /** 384 * 根据节点数据找到对应的节点 385 * @param data 节点数据 386 * @param node 387 * @return 388 */ 389 public BinaryNode<T> getNode(T data,BinaryNode<T> node){ 390 //不存在节点 391 if(this.isEmpty()){ 392 return null; 393 } 394 //先和当前节点的数据比较 395 int compareResult=data.compareTo(node.elem); 396 if(compareResult>0){//进入右子树中继续判断 397 return getNode(data,node.right); 398 }else if(compareResult<0){//进入左子树中继续判断 399 return getNode(data,node.left); 400 }else{//相等 401 return node; 402 } 403 } 404 /** 405 * 打印树结构信息 406 * @param index 遍历的类型 407 * 一般用到的遍历方式有三种: 408 * (1)前序遍历 0 409 * (2)中序遍历 1 410 * (3)后序遍历 2 411 */ 412 public void printTree(int index){ 413 String type=(index==0?"前序":index==1?"中序":"后序")+"遍历"; 414 System.out.println("------------【开始遍历打印·"+type+"】------------"); 415 switch(index){ 416 case 0:preOrder(this.root);break; 417 case 1:inOrder(this.root);break; 418 case 2:postOrder(this.root);break; 419 } 420 System.out.println("------------【打印结束】------------"); 421 } 422 /** 423 * 前序遍历 424 * @param node 遍历的起始节点 425 * 采用递归思想 426 * 对左子节点进行遍历 427 * 对右子节点进行遍历 428 * 递归基值是node是否是null 429 */ 430 private void preOrder(BinaryNode<T> node) 431 { 432 if(node==null){ 433 return; 434 }else{ 435 System.out.print(node.elem+" ");//输出数据节点信息 436 preOrder(node.left); 437 preOrder(node.right); 438 } 439 } 440 /** 441 * 中序遍历 442 * @param node 443 */ 444 private void inOrder(BinaryNode<T> node){ 445 if(node==null){ 446 return; 447 }else{ 448 inOrder(node.left); 449 System.out.print(node.elem+" "); 450 inOrder(node.right); 451 } 452 } 453 /** 454 * 后序遍历 455 * @param node 456 */ 457 private void postOrder(BinaryNode<T> node){ 458 if(node==null){ 459 return; 460 }else{ 461 postOrder(node.left); 462 postOrder(node.right); 463 System.out.print(node.elem+" "); 464 } 465 } 466 /** 467 * 获取指定节点的数据 468 * @param node 469 * @return 470 */ 471 public T getElem(BinaryNode<T> node){ 472 if(node==null){ 473 return null; 474 } 475 return node.elem; 476 } 477 /** 478 * 内置一个树节点类 479 */ 480 private static class BinaryNode<T>{ 481 /** 482 * 树节点存放数据域 483 */ 484 T elem; 485 /** 486 * 左子树节点域 487 */ 488 BinaryNode<T> left; 489 /** 490 * 右子树节点域 491 */ 492 BinaryNode<T> right; 493 /** 494 * 构造器 495 */ 496 public BinaryNode(T elem,BinaryNode<T> left,BinaryNode<T> right){ 497 this.elem=elem; 498 this.left=left; 499 this.right=right; 500 } 501 public T getElem(){ 502 return this.elem; 503 } 504 } 505 } 506
删除功能的代码如下:
(1)根据数据找到二叉树中的结点
1 /** 2 * 根据节点数据找到对应的节点 3 * @param data 节点数据 4 * @param node 5 * @return 6 */ 7 public BinaryNode<T> getNode(T data,BinaryNode<T> node){ 8 //不存在节点 9 if(this.isEmpty()){ 10 return null; 11 } 12 //先和当前节点的数据比较 13 int compareResult=data.compareTo(node.elem); 14 if(compareResult>0){//进入右子树中继续判断 15 return getNode(data,node.right); 16 }else if(compareResult<0){//进入左子树中继续判断 17 return getNode(data,node.left); 18 }else{//相等 19 return node; 20 } 21 }
(2)查找删除数据的上一级节点
1 /** 2 * 根据节点数据找到对应的节点的父节点 3 * @param data 节点数据 4 * @return 5 */ 6 public BinaryNode<T> getPrevNode(T data){ 7 if(this.isEmpty()){//空树 8 return null; 9 } 10 if(data.equals(root.getElem())){ 11 return null; 12 } 13 BinaryNode<T> parNode=this.root;//父节点 14 BinaryNode<T> curNode=this.root;//当前节点 15 while(true){ 16 int compareResult=data.compareTo(curNode.elem); 17 if(compareResult>0){//进入右子树中继续判断 18 /*parNode.elem=curNode.elem; 19 parNode.left=curNode.left; 20 parNode.right=curNode.right;*/ 21 parNode=curNode; 22 curNode=curNode.right; 23 }else if(compareResult<0){//进入左子树中继续判断 24 /*parNode.elem=curNode.elem; 25 parNode.left=curNode.left; 26 parNode.right=curNode.right;*/ 27 parNode=curNode; 28 29 curNode=curNode.left; 30 }else{//相等 31 break; 32 } 33 } 34 return parNode; 35 }
(3)判断二叉树是否包含要删除的数据
1 /** 2 * 判断二叉树中指定节点后面是否包含指定数据 3 * @param target 检索数据target 4 * @param node 指定的节点(包含当前节点) 5 * @return 6 */ 7 public boolean contains(T target,BinaryNode<T> node){ 8 //判空检查 9 if(node==null){ 10 return false; 11 } 12 //先和当前节点的数据比较 13 int compareResult=target.compareTo(node.elem); 14 if(compareResult>0){//进入右子树中继续判断 15 return contains(target,node.right); 16 }else if(compareResult<0){//进入左子树中继续判断 17 return contains(target,node.left); 18 }else{//相等 19 return true; 20 } 21 }
(4)查找二叉树指定结点的左子树中最大的节点
1 /** 2 * 查找指定树节点下面的最大节点[最大的数据在右子树的最深叶子节点] 3 * @param node 指定的查找起点节点 4 * @return 5 */ 6 public BinaryNode<T> findMax(BinaryNode<T> node){ 7 //如果节点为空 8 if(node==null){ 9 return null; 10 }else if(node.right==null){//递归基准情况 11 return node; 12 }else{//递归流程 13 return findMax(node.right); 14 } 15 } 16 /** 17 * 查找整棵树中的最大数据 18 * @return 19 */ 20 public T findMax(){ 21 return this.findMax(this.root).elem; 22 }
(5)*删除指定数据所在的节点
1 /** 2 * 移除二叉树中根节点后面的指定数据(所在的节点) 3 * @param data 指定的数据 4 */ 5 public boolean remove(T data){ 6 boolean ret=false; 7 //要删除的数据所在的结点存在 8 if(!this.contains(data)){ 9 return ret; 10 } 11 //要删除的节点 12 BinaryNode<T> target=this.getNode(data, this.root); 13 if(target!=null){ 14 //要删除的节点的上一级节点 15 BinaryNode<T> parNode= this.getPrevNode(data); 16 System.out.println("parNode==null:"+(parNode==null)); 17 //(1)当前节点为叶子节点 18 if(target.left==null && target.right==null){ 19 target=null; 20 if(parNode!=null){ 21 if(data.compareTo(parNode.elem)>0){//右子树 22 parNode.right=null; 23 }else if(data.compareTo(parNode.elem)<0){//左子树 24 parNode.left=null; 25 } 26 }else{//删除的是根节点 27 this.root=null; 28 } 29 ret=true; 30 } 31 //(2)只有一个子树(左或者右) 32 else if(target.left!=null && target.right==null){ 33 target=target.left; 34 if(parNode!=null){ 35 if(data.compareTo(parNode.elem)>0){//右子树 36 parNode.right=target; 37 }else if(data.compareTo(parNode.elem)<0){//左子树 38 parNode.left=target; 39 } 40 }else{//删除的是根节点 41 this.root=this.root.left; 42 } 43 ret=true; 44 }else if(target.left==null && target.right!=null){ 45 target=target.right; 46 if(parNode!=null){ 47 if(data.compareTo(parNode.elem)>0){//右子树 48 parNode.right=target; 49 }else if(data.compareTo(parNode.elem)<0){//左子树 50 parNode.left=target; 51 } 52 }else{//删除的是根节点 53 this.root=this.root.right; 54 } 55 ret=true; 56 } 57 //(3)左右子树都有 58 /** 59 * 最麻烦的一种删除方式: 60 * [1]找到要删除节点的父节点,判断当前节点是在父节点的左子树还是右子树。 61 * [2]找到当前删除节点的左子树的最大节点,替换当前删除节点。 62 * [3]当前删除节点的左子树的最大节点的父节点(针对这个节点的指向清空) 63 * [4]重新设置新结点的左右子树的指向 64 */ 65 else if(target.left!=null && target.right!=null){ 66 //1.取左子树的最大数据节点 67 BinaryNode<T> lmaxNode=this.findMax(target.left); 68 if(parNode!=null){//删除的非根节点 69 if(data.compareTo(parNode.elem)>0){//右子树 70 //2.左子树最大数据节点的上级节点 71 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 72 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 73 if(lmaxNode.left!=null){ 74 maxParNode.right=lmaxNode.left; 75 }else{ 76 maxParNode.right=null; 77 } 78 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 79 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 80 if(maxParNode.elem.equals(target.elem)){ 81 maxParNode.left=lmaxNode.left; 82 }else{ 83 maxParNode.left=null; 84 } 85 } 86 //3.替换当前删除节点 87 lmaxNode.left=target.left; 88 lmaxNode.right=target.right; 89 parNode.right=lmaxNode; 90 }else if(data.compareTo(parNode.elem)<0){//左子树 91 //2.左子树最大数据节点的上级节点 92 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 93 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 94 if(lmaxNode.left!=null){ 95 maxParNode.right=lmaxNode.left; 96 }else{ 97 maxParNode.right=null; 98 } 99 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 100 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 101 if(maxParNode.elem.equals(target.elem)){ 102 maxParNode.left=lmaxNode.left; 103 }else{ 104 maxParNode.left=null; 105 } 106 } 107 //3.替换当前删除节点 108 lmaxNode.left=target.left; 109 lmaxNode.right=target.right; 110 parNode.left=lmaxNode; 111 } 112 }else{//删除的是根节点 113 //2.左子树最大数据节点的上级节点 114 BinaryNode<T> maxParNode=this.getPrevNode(lmaxNode.getElem()); 115 if(lmaxNode.getElem().compareTo(maxParNode.elem)>0){ 116 if(lmaxNode.left!=null){ 117 maxParNode.right=lmaxNode.left; 118 }else{ 119 maxParNode.right=null; 120 } 121 }else if(lmaxNode.getElem().compareTo(maxParNode.elem)<0){ 122 //特别注意:当maxParNode的上一级就是target的时候,需要特殊处理 123 if(maxParNode.elem.equals(target.elem)){ 124 maxParNode.left=lmaxNode.left; 125 }else{ 126 maxParNode.left=null; 127 } 128 } 129 //3.替换当前删除节点 130 lmaxNode.left=target.left; 131 lmaxNode.right=target.right; 132 this.root=lmaxNode; 133 } 134 ret=true; 135 } 136 } 137 this.nodeCount=(ret==true?--this.nodeCount:this.nodeCount); 138 //找到要删除的节点 139 return ret; 140 }
测试类:
1 package com.xfwl.algorithmAnalysis.trees; 2 3 public class Test { 4 /** 5 * @param args 6 */ 7 public static void main(String[] args) { 8 //创建一棵树 9 MyTreeDefin<Integer> tree=new MyTreeDefin<>(); 10 //压入数据 11 tree.push(5); 12 tree.push(2); 13 tree.push(4); 14 tree.push(8); 15 tree.push(7); 16 tree.push(11); 17 tree.push(3); 18 tree.push(9); 19 tree.push(6); 20 tree.push(1); 21 tree.push(0); 22 tree.push(10); 23 System.out.println(tree.getSize()); 24 //开始遍历显示 25 //tree.printTree(0); 26 //tree.printTree(1); 27 //tree.printTree(2); 28 //删除 29 tree.remove(5); 30 tree.printTree(1); 31 //System.out.println(tree.getSize()); 32 33 //System.out.println(tree.getPrevNodeElem(2)); 34 } 35 }
运行结果比较多,就不一一展示在这里了!
研究技术需要静下心来,一点一点地深究.......