java有序二叉树的删除节点方式
java有序二叉树的删除节点
删除节点时会有三种可能
1、删除的节点为叶子节点
我们如果删除为叶子节点,则步骤应该是:
1)先找到要删除的叶子节点
2)再找到要删除节点的父节点(考虑是否有父节点)
3)找到删除的节点是父节点的左子树还是右子树
4)根据前面的情况进行删除
2、删除的节点只有一个子树
步骤:
1)先找到要删除的节点
2)再找到要删除节点的父节点(考虑是否有父节点)
3)确定删除的节点是有左子树还是有右子树
4)找到删除的节点是父节点的左子树还是右子树
5)根据前面的情况进行删除
3、删除的节点有两个子树
步骤:
1)先找到要删除的节点
2)再找到要删除节点的父节点(考虑是否有父节点)
3)找到删除节点右子树当中最小的或左子树最大的节点
4)将3)找到的这个节点的值替换掉要删除的节点的值
5)删除找到的3)
通过上面步骤它们都有一个共同特点就是需要找到删除的节点和要删除节点的父节点,所以我们可以把这两个找节点都写成方法:
找到删除节点代码如下(通过递归的方式找到要删除节点位置并记录下来):
//找到要删除的节点 public TreeNode searchDelnode(TreeNode node,Integer val) { if(node==null) { return null; } if(node.val==val) { return node; }else if(val>node.val){ if(node.rightNode==null) { return null; } return searchDelnode(node.rightNode, val); }else { if(node.leftNode==null) { return null; } return searchDelnode(node.leftNode, val); } }
找被删除节点的父节点代码如下所示:
//找到要删除节点的父节点 public TreeNode searchDelpartent(TreeNode node,Integer val) { if(node==null) { return null; } if((node.leftNode!=null&&node.leftNode.val==val)||(node.rightNode!=null&&node.rightNode.val==val)) { return node; }else { if(node.leftNode!=null&&val<node.val) { return searchDelpartent(node.leftNode, val); }else if(node.rightNode!=null&&val>node.val){ return searchDelpartent(node.rightNode, val); }else { return null; } } }
我们可以根据以上步骤写删除方法代码:
//二叉树删除节点 public void del(TreeNode node,Integer val) { if(node==null) { return; } //1.找到要删除的节点 TreeNode targetNode=searchDelnode(node, val); //2.没有找到要删除的节点 if(targetNode==null) { return; } //3.找到要删除节点的父节点 TreeNode parentNode=searchDelpartent(node, val); if(node.rightNode==null&&node.leftNode==null) { root=null; return; } if(parentNode==null&&(targetNode.rightNode!=null||targetNode.leftNode!=null)) { int min=searchRightMin(targetNode.rightNode); targetNode.val=min; return; } if(targetNode.leftNode==null&&targetNode.rightNode==null) { if(parentNode.rightNode!=null&&parentNode.rightNode.val==targetNode.val) { parentNode.rightNode=null; }else if(parentNode.leftNode!=null&&parentNode.leftNode.val==val){ parentNode.leftNode=null; } }else if(targetNode.leftNode!=null&&targetNode.rightNode!=null) { //在删除节点由左右两个子树时,我们选择找删除节点右子树的最小值,我们可以写一个方法,在这个方法里不仅找到最小值,并把这个位置的元素进行删除 int min=searchRightMin(targetNode.rightNode); targetNode.val=min; }else { if(targetNode.rightNode!=null) { if(parentNode.rightNode.val==targetNode.val) { parentNode.rightNode=targetNode.rightNode; }else { parentNode.leftNode=targetNode.rightNode; } }else{ if(targetNode.rightNode.val==targetNode.val) { parentNode.rightNode=targetNode.leftNode; }else { parentNode.leftNode=targetNode.leftNode; } } } }
在删除节点由左右两个子树时,我们选择找删除节点右子树的最小值,我们可以写一个方法,在这个方法里不仅找到最小值,并把这个位置的元素进行删除
代码如下:
public int searchRightMin(TreeNode node) { TreeNode temp=node; while(temp.leftNode!=null) { temp=temp.leftNode; } del(root, temp.val); return temp.val; } }
写一个测试类进行测试:
public class Test { public static void main(String[] args) { BinaryTree binaryTree=new BinaryTree(); binaryTree.insert(1); binaryTree.insert(2); binaryTree.insert(3); binaryTree.insert(4); binaryTree.insert(5); binaryTree.insertDigui(6, binaryTree.root); binaryTree.insertDigui(7, binaryTree.root); binaryTree.insertDigui(8, binaryTree.root); binaryTree.insertDigui(9, binaryTree.root); binaryTree.del(binaryTree.root, 2); binaryTree.Order(); System.out.println(); binaryTree.startErgodic(binaryTree.root); System.out.println(); binaryTree.midErgodic(binaryTree.root); System.out.println(); binaryTree.endErgodic(binaryTree.root); } }
结果如下图所示:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
SpringBoot如何通过配置文件(yml,properties)限制文件上传大小
这篇文章主要介绍了SpringBoot如何通过配置文件(yml,properties)限制文件上传大小,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03Java之SpringCloud Eurka注册错误解决方案
这篇文章主要介绍了Java之SpringCloud Eurka注册错误解决方案,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下2021-07-07Spring的@Validation和javax包下的@Valid区别以及自定义校验注解
这篇文章主要介绍了Spring的@Validation和javax包下的@Valid区别以及自定义校验注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-01-01SpringSecurity oAuth2.0的四种模式(小结)
本文主要介绍了SpringSecurity oAuth2.0的四种模式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2022-02-02
最新评论