二叉树的删除分为删除叶子节点,删除只有一个子树的节点和删除有两个子树的节点,不确定性很高,所以说是非常的复杂。那我们一个一个的来说。
1.删除叶子节点
2.删除只有一个子树的节点
3.删除有两个子树的节点
代码实现:
/**
* 找到被删除的节点
* @param node 树
* @param value 删除节点的值
* @return node 节点
*/
public TreeNode search(TreeNode node, int value){
// 首先判断根节点是否为空
if(root == null) {return null;}
if(node.value == value){
// 一步找到直接返回
return node;
//值小了往左找
} else if(node.value > value){
if(node.leftChild == null){return null;}
//左边没有就是真的没有
//递归调用函数
return search(node.leftChild,value);
} else{
//右边同理
if(node.rightChild == null) {return null;}
return search(node.rightChild,value);
}
}
/**
* 找删除节点的父节点
* @param node 树
* @param value 删除的值
* @return node 节点
*/
public TreeNode searchParent(TreeNode node, int value) {
if (root == null) {
return null;
}
//判断我们当前的节点的左或右孩子是不是我们要删除的值
if (node.leftChild != null && node.leftChild.value == value) {
return node;
} else if (node.rightChild != null && node.rightChild.value == value) {
return node;
} else {
// 往左走
if (node.leftChild != null && value < node.value) {
return searchParent(node.leftChild, value);
} else if (node.rightChild != null && value > node.value) {
//向右走
return searchParent(node.rightChild, value);
} else {return null;}
//没有父节点
}
}
/**
* 找左子树中的最小值并删除的方法
* @param node 树
* @return value 删除的值
*/
public int searchRightMin(TreeNode node){
//定义一个指针
TreeNode tempNode = node;
while (tempNode.leftChild !=null){
tempNode = tempNode.leftChild;
}
delete(root,tempNode.value);
return tempNode.value;
}
/**
* 删除方法
* @param node 树
* @param value 删除的值
*/
public void delete(TreeNode node,int value){
if (node == null){return;}
// 1.找到删除的节点
TreeNode targetNode = search(node,value);
// 2.如果没有删除的节点
if (targetNode == null){
System.out.println("要删除的节点不存在");
return;
}
//如果这颗树只有一个节点,那就直接干掉完事
if (node.leftChild == null && node.rightChild == null){
root = null;
return;
}
//3.找到targetNode的父节点
TreeNode parentNode = searchParent(node,value);
//删除的节点是叶子节点
if (targetNode.rightChild == null && targetNode.leftChild == null){
if (parentNode.leftChild !=null && parentNode.leftChild.value.equals(targetNode.value)){
parentNode.leftChild = null;
}else if (parentNode.rightChild !=null && parentNode.rightChild.value.equals(targetNode.value)){
parentNode.rightChild = null;
}
//删除的是有两个子树的节点
}else if(targetNode.rightChild!=null && targetNode.leftChild !=null){
//找到删除节点右子树当中最小的
int minValue = searchRightMin(targetNode.rightChild);
targetNode.value = minValue;
//删除只有一个子树的节点
}else {
//如果删除的节点有左子树
if (targetNode.leftChild != null){
if (parentNode.leftChild.value.equals(targetNode.value)){
//删除的节点是父节的左子树
parentNode.leftChild = targetNode.leftChild;
}else {//删除的节点是父节的右子树
parentNode.rightChild = targetNode.leftChild;
}
}else {
if (parentNode.leftChild.value.equals(targetNode.value)){
parentNode.leftChild = targetNode.rightChild;
}else {
parentNode.rightChild = targetNode.rightChild;
}
}
}
}