欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode 450. 删除二叉搜索树中的节点

程序员文章站 2022-05-20 08:53:48
...
  • 题目:

给定一个二叉搜索树的根节点 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++)

 TreeNode* findMin(TreeNode* root){             //找到最右端的节点
        while(root->left){
           root = root->left;
        }
        return root;
    }
    TreeNode* findMax(TreeNode* root){            //找到最左端的节点
        while(root->right){
            root = root->right;
        }
        return root;
    }
    TreeNode* deleteNode(TreeNode* &root, int key) {                   //这里需要引用指针
        if(root == nullptr)
            return root;
        if(root->val == key){
            if(root->left == nullptr && root->right == nullptr){
                root= nullptr;
            }
            else if(root->left != nullptr){
                TreeNode* temp = findMax(root->left);   //查找前驱
                root->val = temp->val;                             //覆盖
                deleteNode(root->left, temp->val);         //递归删除前驱
            }else if(root->right != nullptr){           //查找后继
                TreeNode* temp = findMin(root->right);   
                root->val = temp->val;                                //覆盖
                deleteNode(root->right, temp->val);          //递归删除后继
            }
        }else if(root->val > key){                     //节点值大于需要查找的值,在左子树中删除
            deleteNode(root->left, key);
        }else{
            deleteNode(root->right, key);              //节点值小于查找值,在右子树中删除
        }
        return root;
    }