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;
}
};