1. 程式人生 > >LeetCode 450——二叉搜尋樹的節點刪除c++版本

LeetCode 450——二叉搜尋樹的節點刪除c++版本

把題面給大家放一哈

給定一個二叉搜尋樹的根節點 root 和一個值 key,刪除二叉搜尋樹中的 key 對應的節點,並保證二叉搜尋樹的性質不變。返回二叉搜尋樹(有可能被更新)的根節點的引用。

一般來說,刪除節點可分為兩個步驟:

  1. 首先找到需要刪除的節點;
  2. 如果找到了,刪除它。

說明: 要求演算法時間複雜度為 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;
    }
};