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