二叉搜索树删除元素likou450

本题我自己做只得了80%左右,主要是删除根节点时没处理好。

这一题我吸取的上一题的教训,用了二叉搜索树的特性:

左节点小于根节点

右节点大于根节点

所以我们的递归还是得使用三个主判断:

小于、大于、等于指定元素时怎么做:

根节点值小于指定元素时,就说明在需要删除的元素在右边、向右递归

根节点值大于指定元素时,就在左边、向左递归。

等于时,就要进行删除操作:

        分为三个条件:

        1、待删除节点左、右节点都是空时,就说明是叶子节点,后面什么都没了,直接返回null。

        2、左节点为空或者右节点为空,就说明需要返回非空节点下面的子树,将非空的节点子树返回就好了。

        3、左、右节点都不为空时,这个时候就比较麻烦了:删除节点后,要保持二叉搜索树的特性,所以就得怎么做:

        将待删除节点的左节点全部加入到待删除节点右子树的左子叶上、

        因为删除节点的右节点一定比左节点大,而且它也是二叉搜索树,它的左节点一定是整颗二叉树合理的地方。

 

package shuJuJieGouYuSuanFa.erChaShu;

public class likou450 {
    public static void main(String[] args) {
        TreeNode root = TreeNode.getBST();
        int key = 8;
        TreeNode ans = new likou450().deleteNode(root, key);
        peint(ans);
    }
//打印输出二叉树,前序遍历
    private static void peint(TreeNode ans) {
        if (ans == null) {
            return;
        }
        System.out.print(ans.val + " ");
        peint(ans.left);
        peint(ans.right);
    }

    public TreeNode deleteNode(TreeNode root, int key) {
        return dfs(root, key);
    }

    private TreeNode dfs(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        if (root.val < key) {
            root.right = dfs(root.right, key);
        } else if (root.val > key) {
            root.left = dfs(root.left, key);
        } else {
            if (root.left == null && root.right == null) {
                return null;
            } else if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            } else if (root.left != null && root.right != null) {
                TreeNode t = root.right;
                while (t.left != null) {
                    t = t.left;
                }
                t.left = root.left;
                root = root.right;
                return root;
            }
        }
        return root;
    }
}

 难度还是有点的,自己带得努力,暗自加油吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值