删除二叉搜索树中的节点(leetcode450)

二叉搜索树的节点删除

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

二叉搜索树的删除相对于添加要难的多,需要考五种情况

  1. 树中不存在要删除的元素

  2. 删除节点没有左右孩子节点,直接删除

  3. 删除节点只有右孩子,没有左孩子,把右孩子接在根节点上

  4. 删除节点只有左孩子,没有右孩子,把左孩子接在根节点上

  5. 删除节点左右都有孩子,把左孩子放在右孩子的最左边节点上,然后用右孩子替换根节点

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        return delete(root, key);
    }
​
    public TreeNode delete(TreeNode root, int key) {
        //第一种情况,没有找到要删除的节点
        if (root == null) {
            return null;
        }
        //树中有要删除节点,找到节点key == root.val
        if (root.val == key) {
​
            //第二种情况,节点没有左右孩子,直接删除
            if (root.left == null && root.right == null) return null;
            //第三种情况,节点有右孩子,没有左孩子
            if (root.left == null) return root.right;
            //第四种情况,节点有左孩子,没有右孩子
            if (root.right == null) return root.left;
            //第五种情况,节点左右都有孩子,则右孩子替换被删除节点,左孩子放在右孩子的最左侧节点处
            TreeNode cur = root.right;
            while (cur.left != null) {
                cur = cur.left;
            }
            cur.left = root.left;
            root = root.right;
            return root;
        }
        if (key > root.val) root.right = delete(root.right, key);
        if (key < root.val) root.left = delete(root.left, key);
        return root;
    }
}

类似题目

669. 修剪二叉搜索树

看过删除二叉搜索树中节点这道题后,想当然的就认为,本体只需要对二叉搜索树树进行遍历,遇到不在范围内的节点,直接调用删除二叉搜索树中指定节点的方法,就可以了。

这么想当然没错,但是本题可以有更简单的解题思路:利用好二叉搜索树的特性

  • 当前节点如果小于指定范围,则其左子树的所有节点一定也小于指定范围。则删除的时候,只用当作节点只有右孩子的情况删除该节点即可(连带着左子树一起删除)

  • 当前节点如果大于指定范围,则其右子树的所有节点一定也小于指定范围。则删除的时候,只用当作节点只有左孩子的情况删除该节点即可(连带着右子树一起删除)

所以直接先序遍历,然后找到不在范围的节点,按照上面两个规则进行删除即可

如图所示,范围为:[2,7],则遍历到1的时候,可以将1和其左子树一起扔掉,让2接到3的左子树,再递归进行判断,右子树同理。

 

  1. 确定递归函数饿返回值和参数

    public TreeNode trimBST(TreeNode root, int low, int high)
  2. 确定递归边界

    if(root == null) return root;
  3. 写递归体

    if(root.val < low) {
        return trimBST(root.right, low,high);//将该节点的右孩子返回(删掉该节点和其左孩子)
    }
    if(root.val > low) {
        return trimBST(root.left, low,high);//将该节点的左孩子返回(删掉该节点和其右孩子)
    }
    root.left = trimBST(root.left, low, high);//用来接左孩子的返回值,这样return trimBST(root.right, low,high);的返回值才有意义
    root.right = trimBST(root.right, low, high);//同理

 

 

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null) return root;
        if(root.val < low) {
            return trimBST(root.right, low, high);
        }
        if (root.val > high) {
            return trimBST(root.left, low, high);
        }
        root.left = trimBST(root.left,low,high);
        root.right = trimBST(root.right,low,high);
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值