题意:删除二分搜索树中值为key的结点
算法思路:当root为null时,直接返回root。首先,用二分搜索法查找到值为key的结点,在查找的过程中记录该结点的父结点并标记该结点是父结点的左孩子还是右孩子(用于保存删除某结点时涉及到的其他结点)。若没有找到key值的结点,则原样返回。若父结点为null,说明删除的结点是根结点,如果 root.left为null,则root指向root.right,else 如果root.right为null,则root指向root.left,else 说明左右孩子都不为空,则将右子树挂在左子树的最右端,更新root为其左孩子。若父结点不为null,说明删除的结点不在根结点上,和上面的思路非常相似,其实就多了一个父结点,因为前面已经记录了被删除的结点是否为父结点的右孩子,依然分析被删除结点左右孩子情况,进行相应的逻辑处理,这里不再赘述。
我在leetcode上提交的结果:Runtime: 6 ms, faster than 79.64% of Java online submissions for Delete Node in a BST.
附上代码:
//leetcode 450. Delete Node in a BST
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null)
return root;
TreeNode p = root;
boolean r=false;//识别被删除节点的父节点是否为右孩子
TreeNode father = null;
while(p!=null){
if(p.val==key)
break;
else if(key<p.val){
father = p;
r = false;
p = p.left;
}else{
father = p;
r = true;
p = p.right;
}
}
if(p==null)
return root;
if(father==null){
if(root.left==null)
root = root.right;
else if(root.right==null)
root = root.left;
else{
TreeNode rchild = root.right;
root = root.left;
TreeNode qNode = root;
while(qNode.right!=null){
qNode = qNode.right;
}
qNode.right = rchild;
}
return root;
}else{
if(p.left==null){
if(r)
father.right = p.right;
else
father.left = p.right;
}else if(p.right==null){
if(r)
father.right = p.left;
else
father.left = p.left;
}else{
TreeNode rchild = p.right;
TreeNode qNode = p.left;
if(r)
father.right = p.left;
else
father.left = p.left;
while(qNode.right!=null)
qNode = qNode.right;
qNode.right = rchild;
}
return root;
}
}