LeetCode 450. 刪除二叉搜尋樹中的節點(C++)
阿新 • • 發佈:2019-02-01
給定一個二叉搜尋樹的根節點 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
思路:
找到需要刪除的節點之後,關於節點刪除的規則如下:
1. 如果該節點是葉子節點,直接刪除該節點即可。
2. 如果該節點不是葉子節點,但是隻有左孩子或者右孩子的話,先交換該節點與其左孩子或者右孩子的值,然後刪除其左孩子或者右孩子。
3. 如果該節點既有左孩子,又有右孩子的話,可以採用如下方式進行調整(這裡對該節點的右子樹進行調整,左子樹調整同理)
(1)先新建一個指標,指向要刪除節點的右孩子。
(2)由於右孩子可能本身存在左孩子,即delNode->right->left != NULL
delNode->right->left->val
是小於delNode->right->val
的,所以直接向delNode->right->val
賦值給要刪除的節點是不可取的,因此要先要找到刪除節點的右子樹中的最小節點,即遞迴判斷刪除節點的右孩子的左孩子是否存在。 (3)找到刪除節點右子樹的最小節點
minRNode
,將其與要刪除的節點delNode
交換取值,然後刪除minRNode
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == NULL)
return NULL;
if(root->val == key){
if(root->left != NULL && root->right != NULL){
TreeNode* minRNode = root->right;
while(minRNode->left != NULL)
minRNode = minRNode->left;
root->val = minRNode->val;
root->right = deleteNode(root->right, minRNode->val);
}
else{
if(root->left != NULL){ //僅有左孩子
root->val = root->left->val;
delete(root->left);
}
else if(root->right != NULL){ //僅有右孩子
root->val = root->right->val;
delete(root->right);
}
else{ //無孩子
delete(root);
}
}
return root;
}
if(key > root->val)
root->right = deleteNode(root->right, key);
else if(key < root->val)
root->left = deleteNode(root->left, key);
return root;
}
};