450. 删除二叉搜索树中的节点
问题
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
- 首先找到需要删除的节点;
- 如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
示例:
root = [5,3,6,2,4,null,7] key = 3 5 / \ 3 6 / \ \ 2 4 7 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 5 / \ 4 6 / \ 2 7 另一个正确答案是 [5,2,6,null,4,null,7]。 5 / \ 2 6 \ \ 4 7
思路
第一种情况是,如果要删除的节点没有子节点,如果要删除的节点没有子节点,我们只需要直接将父节点中,指向要删除的节点的指针设置为null
第二种情况是,如果要删除的节点只有一个子节点(只有左子节点或右子节点),我们只需要更新父节点中,指向要删除节点的指针,让它指向要删除节点的子节点就可以了
第三种情况是,如果要删除的节点有两个子节点,这就比较复杂了。我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上。然后再删除掉这个最小节点,因为最小节点肯定没有左子节点(如果有左子结点,那就不是最小节点了),所以,我们可以应用上面两条规则来删除这个最小节点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
TreeNode p=root;
TreeNode pp=null;
while(p!=null&&p.val!=key) {
pp=p;
if(p.val>key)
p=p.left;
else
p=p.right;
}
if(p==null)
return root;
if(p.left!=null&&p.right!=null){
TreeNode minP=p.right;
TreeNode minPP=p;
while(minP.left!=null){
minPP=minP;
minP=minP.left;
}
p.val=minP.val;
p=minP;
pp=minPP;
}
TreeNode child=null;
if(p.left!=null)
child=p.left;
else if(p.right!=null)
child=p.right;
else
child=null;
if(pp==null)
root=child;
else if(pp.left==p)
pp.left=child;
else
pp.right=child;
return root;
}
}