LeetCode 450——二叉搜尋樹的節點刪除c++版本
阿新 • • 發佈:2018-12-14
把題面給大家放一哈
給定一個二叉搜尋樹的根節點 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
我們首先給出第一種c++寫法,這也是最為簡單易懂的暴力解法~
主要思想就是按照目標節點的度進行分類,從而細化到每一種情況進行列舉。
/** * 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) { TreeNode *p1 = root; TreeNode *p2 = NULL; while(p1&&p1->val!=key) { p2 = p1; if(key>p1->val) { p1 = p1->right; } else if(key<p1->val) { p1 = p1->left; } } if(!p1) return root; //如果度為0 if(p1&&!p1->left&&!p1->right) { if(p2) { if(p1 == p2->left) p2->left = NULL; else if(p1 == p2->right) p2->right = NULL; } else return NULL; } //如果度為1 else if(!p1->left||!p1->right) { if(!p2) { if(p1->left) return p1->left; else return p1->right; } if(p1->left) { if(p1==p2->right) p2->right = p1->left; else if(p1==p2->left) p2->left =p1->left; } else if(p1->right) { if(p1==p2->right) p2->right = p1->right; else if(p1==p2->left) p2->left =p1->right; } } //如果度為2 else if(p1->left&&p1->right&&p1) { TreeNode *parent = NULL; TreeNode *a = NULL; TreeNode *target = NULL; target = p1; //在這裡我們選擇兩種正確答案中找直接後繼的這一種 parent = p1; p1 = p1->right; while(p1->left) { parent = p1; p1 = p1->left; } target->val = p1->val; if(p1 == parent->right) parent->right = p1->right; else if(p1 == parent->left) parent->left = p1->right; } return root; } };