【LeetCode450】Delete Node in BST二叉搜索树删除节点

一、原题重现

题干中给定一个二叉搜索树(BST)的根节点以及一个给定的值,要求我们删除BST中与该值相等的节点,并且删除节点后,该树仍旧满足二叉搜索树的性质。下面举出一个例子

root = [5,3,6,2,4,null,7]
key = 3

    5
   / \
  3   6
 / \   \
2   4   7

给定的有效值Key为 3,因此我们需要在该BST中删除值为3的节点。
下面是删除节点后所得到的一个有效的BST

    5
   / \
  4   6
 /     \
2       7
二、思路分析

二叉搜索树最大的特点就是左孩子节点的值小于或等于根节点,右孩子节点的值大于或等于根节点,再延伸一点就是左子树的每一个节点值都要小于根节点,而右子树的每一个节点值一定大于根节点。因此在删除原有节点后,树的结构需要作出一些调整后才能继续满足这个性质,这个调整也是这题的难点所在。

那么对于一个节点来说,它的可能情况就是只有左孩子,只有右孩子,左孩子右孩子都有,左孩子右孩子都没有。我们对于删除节点后树的调整也分为这四种情况进行。第一种,当被删除节点只有左孩子节点时,我们只需要将其左孩子节点替换掉该节点即可。当被删除节点只有右孩子节点时,同样的,我们只需要将右孩子节点替换掉该节点即可。当被删除节点既没有左孩子节点也没有右孩子节点时,即为叶节点,直接将该节点变为空值,即ROOT=NULL。当即有左孩子节点又有右孩子节点时,这时的变化较为复杂些,我们选择在被删除节点中找到它右子树中最小的那个节点,该节点一定是处于右子树的叶节点中,我们可以先将该叶节点的值赋予给被删除节点,然后将该叶节点赋予空值,即将该叶节点去替换掉被删除节点。

通过以上的思路,我们可以顺利删除节点使得BST仍然成立。只是在第四种情况下,还需要去寻找出右子树中的最小值节点。通过BST的规律我们可知,右子树的最小节点一定是该子树中最左边的那个叶节点,我们只需不断递归找出该子树中最左边那个叶节点即可。

三、C++代码实现

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root == NULL) return NULL;
        if(root->val > key) {
            root->left = deleteNode(root->left,key);
        } else if(root->val < key) {
            root->right = deleteNode(root->right,key);
        } else {
            if(root->left == NULL) {
                root = root->right;
            } else if(root->right == NULL) {
                root = root->left;
            } else {
                root->right = deleteMin(root->right);
                root->val = min->val;
            }
        }
        return root;
    }
    TreeNode* deleteMin(TreeNode* root){
        if(root == NULL) return root;
        if(root->left == NULL) {
            min = root;
            return root->right;
        }
        root->left = deleteMin(root->left);
        return root;
    }
private:
    TreeNode* min;
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值