[LeetCode] 450. Delete Node in a BST

Delete Node in a BST

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
Basically, the deletion can be divided into two stages:
1. Search for a node to remove.
2. If the node is found, delete the node.
Note: Time complexity should be O(height of tree).
Example:
在这里插入图片描述

解析

删除给定值得节点

解法1:递归

首先判断根节点是否为空,由于BST的性质,可以递归定位到要删除的节点。当前节点不等于key时,根据大小关系递归调用左右节点。
当前节点就是要删除的节点时,首先判断是否有一个子节点不存在,将root指向存在的子节点;当左右子节点都存在时,在右子树中找到最小值得节点,并将其值赋给当前节点,再递归调用右子树删除其最小节点。

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(!root) 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 || !root->right)
                root = root->left ? root->left:root->right;
            else{
                TreeNode* cur = root->right;
                while(cur->left) cur = cur->left;
                root->val = cur->val;
                root->right = deleteNode(root->right, cur->val);
            }
        }
        return root;
    }
};

解法2:迭代

首先构建一个父节点pre以及当前节点cur,找到key的节点位置为cur,如果cur为空返回root,如果pre为空说明删除节点是根节点,调用del函数删除cur,如果删除节点是pre->left,调用del删除cur,并且pre->left=del(cur),反之,pre->right=del(cur)。
下面解释删除函数del(node)。
删除函数是为了删除当前节点,所以当node为叶子结点时,返回NULL;
当node有一个子节点时,返回那个子节点;
当node有两个子节点时,先在右子树中找到最小值节点cur, 并记录其父节点pre,并赋值给node,当pre为node时,node->right = cur->right,反之,pre->right = cur->right;返回node。

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        TreeNode* cur = root, *pre = NULL;
        while(cur){
            if(cur->val == key) break;
            pre = cur;
            if(cur->val > key)
                cur = cur->left;
            else
                cur = cur->right;
        }
        if(!cur) return root;
        if(!pre) return del(cur);
        if(pre->left && pre->left->val == key) 
            pre->left = del(cur);
        else
            pre->right = del(cur);
        return root;
    }
    
    TreeNode* del(TreeNode* node){
        if(!node->left && !node->right) return NULL;
        if(!node->left || !node->right)  
            return node->left ? node->left : node->right;
        TreeNode* pre = node, *cur = node->right;
        while(cur->left){
            pre = cur;
            cur = cur->left;
        }
        node->val = cur->val;
        if(pre == node)
            node->right = cur->right;
        else
            pre->left = cur->right;
        return node;
    }
};

解法3:通用二叉树

遍历所有节点,然后删除值为key的节点

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (!root) return NULL;
        if (root->val == key) {
            if (!root->right) return root->left;
            else {
                TreeNode *cur = root->right;
                while (cur->left) cur = cur->left;
                swap(root->val, cur->val);
            }
        }
        root->left = deleteNode(root->left, key);
        root->right = deleteNode(root->right, key);
        return root;
    }
};

参考

http://www.cnblogs.com/grandyang/p/6228252.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值