规则:处理具有两个儿子的节点,一般的删除策略是用其右子树的最小数据代替该节点的数据,并删除右子树最小数据的那个节点。
public TreeNode2 findMin(TreeNode2 node){ //寻找查找二叉树中最小值节点(即不断遍历左子树)
if(node == null){
return null;
}
else {
while(node.leftChild != null){
node = node.leftChild;
}
}
return node;
}
public void delete(int data, TreeNode2 node){ //data为输入的要删除的值,node为输入的root节点
TreeNode2 minNode = null;
TreeNode2 parent = null;
if(node == null){
return ;
}
else {
while(data != node.data && node != null){ //查找需要删除的node节点
parent = node;
if(data < node.data){
node = node.leftChild;
}
else if(data > node.data){
node = node.rightChild;
}
if(node == null) {
System.out.println("查无此值");
return ;
}
}
if(node.rightChild != null){ //当前要删除的节点存在右子节点时(可能同时存在左子节点)
minNode = findMin(node.rightChild); //找到node节点的右子树的最小值
node.data = minNode.data; //该最小值替代当前节点的值
if(minNode.rightChild != null){ //最小值节点的右子节点不为空
minNode.parent.leftChild = minNode.rightChild; //删除最小值节点,改变指针
}
else { //由于最小值节点不存在左子节点,则此时minNode为叶子节点
if(minNode == minNode.parent.leftChild) {
minNode.parent.leftChild = null;
}
if(minNode == minNode.parent.rightChild) {
minNode.parent.rightChild = null;
}
}
}
else if(node.leftChild != null){ //当前要删除的节点只存在左子节点时,直接删除
if(parent.leftChild == node){
parent.leftChild = node.leftChild; //通过改变指针
}
if(parent.rightChild == node){
parent.rightChild = node.leftChild;
}
}
else { //当前要删除的节点为叶子节点时,直接删除即可
if(parent.leftChild == node){
parent.leftChild = null;
}
if(parent.rightChild == node){
parent.rightChild = null;
}
}
}
}