二叉树的删除
1、分类讨论
如图 节点可以分为3种类型
- 0个子树:删除①,先寻找 ①,再寻找①的父节点②,通过父节点②指向空(null)来实现删除①。
- 1个子树:删除⑦,先寻找 ⑦,再寻找⑦的父节点⑤,让⑤直接指向⑦的左或者右子树来实现删除⑦。
- 2个子树:删除②,先寻找 ②,找到②右子树的最小值或者左子树的最大值,将②变成那个值,并删除那个值。
2、代码
search通过value值找到目标节点,使用递归的方法查找
public TreeNode search(TreeNode root,Integer value) {
TreeNode temp=root;
if(temp==null) {
return null;
}
if(temp.value==value) {
return temp;
}else if(temp.value>value) {
return search(temp.leftChild,value);
}else {
return search(temp.rightChild,value);
}
}
public TreeNode searchParent(TreeNode root,Integer value) {
TreeNode temp=root;
if(temp==null) {
return null;
}
if((temp.rightChild!=null&&temp.rightChild.value==value)||(temp.leftChild!=null&&temp.leftChild.value==value)) {
return temp;
}else {
if(temp.leftChild !=null && value < temp.value) {
return searchParent(temp.leftChild,value);
}else if(temp.rightChild !=null && value > temp.value){
return searchParent(temp.rightChild,value);
}else {
return null;
}
}
}
public Integer min(TreeNode node) {
TreeNode temp=node;
while(temp.leftChild!=null) {
temp=temp.leftChild;
}
delete(root,temp.value);
return temp.value;
}
public void delete(TreeNode root,Integer value) {
if(root==null) {
return;
}
TreeNode target=search(root,value);
if (target == null){
System.out.println("没有删除的节点");
return;
}
//如果树只有一个节点
if (root.leftChild == null && root.rightChild == null){
root = null;
return;
}
TreeNode parent=searchParent(root,value);
//没有左右子树,为叶子结点
if(target.leftChild==null&&target.rightChild==null) {
if(parent.leftChild!=null&&parent.leftChild.value==target.value) {
parent.leftChild=null;
}else {
parent.rightChild=null;
}
}else if(target.leftChild!=null&&target.rightChild!=null) {//有两个子树
int min=min(target.rightChild);
target.value=min;
}else {//只有一个子树
if(target.leftChild!=null) {
if(parent.leftChild.value==value) {
parent.leftChild=target.leftChild;
}else {
parent.rightChild=target.leftChild;
}
}else {
if(parent.leftChild.value==value) {
parent.leftChild=target.rightChild;
}else {
parent.rightChild=target.rightChild;
}
}
}
}