9、二分搜索树的删除(下篇)

一、简单介绍。

1、二分搜索树的删除操作,其实并不简单,我们需要找到我们要删除的元素。然后分情况考虑。

第一种,没有左孩子,我们直接获取一个节点,保持其右孩子,然后进行让要删除的节点的右孩子至于空,然后返回其右孩子。

第二种,没有右孩子,我们直接获取一个节点,保存其左孩子,然后进行让要删除节点的左孩子至于空,然后返回其左孩子。

第三种,左右孩子都为空,我们直接返回空。

第四种,如果左右孩子都不为空,我们获取该节点的前驱节点或者后继节点,来替换它的位置。

2、在删除某个节点之前,我们先来讨论下一些特使情况的处理。

第一种,删除最小节点。我们可以获取的是左子树最左的节点。

第二种,删除最大节点。我们可以获取的是右子树左右边的节点。

二、代码实现

1、获取最小元素

   /**
     * 寻找二分搜索树的最小元素
     */
    public T minimum() {
        if (size == 0) {
            throw new IllegalArgumentException("该树的没有节点");
        }
        Node node = minimum(root);
        return node.e;
    }

    /**
     * 寻找二分搜索树的最小元素。
     *
     * @param node
     * @return
     */
    private Node minimum(Node node) {
        if (node.left == null) {
            return node;
        }
        return minimum(node.left);
    }

2、获取最大元素

 /**
     * 寻找二分搜索树的最大元素
     */
    public T maximum() {
        if (size == 0) {
            throw new IllegalArgumentException("该树的没有节点");
        }
        return maximum(root).e;
    }

    private Node maximum(Node node) {
        if (node.right == null) {
            return node;
        }
        return maximum(node.right);
    }

3、删除最小元素

 /**
     * 移除二分搜索树中的元素
     * 从二分搜索树中删除最小值所在节点, 返回最小值
     */

    public T removeMin() {
        T res = minimum();
        root = removeMin(root);
        return res;
    }

    /**
     * 删除最小节点并返回删除后的树的根节点
     *
     * @param node
     * @return
     */
    private Node removeMin(Node node) {
        if (node.left == null) {  //表示要删除的是该节点。
            Node nodeRight = node.right;
            node.right = null;
            size--;
            return nodeRight;
        }
        node.left = removeMin(node.left);  //如果不是,就继续向左找。
        return node;
    }

4、删除最大元素

  /**
     * 删除最大元素
     *
     * @return
     */
    public T removeMax() {
        T res = maximum();
        root = removeMax(root);
        return res;
    }

    /**
     * 删除当前子树的最大节点,并返回根节点、
     *
     * @param node
     * @return
     */
    private Node removeMax(Node node) {

        if (node.right == null) {  //表示的是找到了最大元素
            Node leftNode = node.left;
            node.left = null;
            size--;
            return leftNode;
        }
        node.right = removeMax(node.right); //没有找到就去右子树继续找。
        return node;
    }

5、删除指定的元素

  /**
     * 删除指定的元素
     *
     * @param t
     */
    public void remove(T t) {
        root = remove(root, t);
    }

    /**
     * 删除指定的元素,并返回删除节点后,返回新树的根节点。
     *
     * @param node
     * @param t
     * @return
     */
    private Node remove(Node node, T t) {

        if (node == null) {  //如果删除的节点不存在就返回空节点。表示删除的节点不存在。
            return null;
        }
        if (node.e.compareTo(t) > 0) {  //表示的是要删除的节点小
            root.left = remove(node.left, t);
        } else if (node.e.compareTo(t) < 0) {//表示的是要删除的节点大
            node.right = remove(node.right, t);
        } else {

            if (node.left == null) {  //如果删除的节点的左节点为null
                Node nodeRight = node.right;  //获取右边节点
                node.right = null;
                size--;
                return nodeRight;
            }
            if (node.right == null) {  //如果被删除的元素右节点为Null
                Node nodeLeft = node.left;
                node.left = null;
                size--;
                return nodeLeft;
            }

            //最后一个情况就是左右元素都不为null;

            //1、找出右边的最小节点  后继节点
            Node successor = minimum(node.right);
            successor.left = node.left;
            successor.right = removeMin(node.right);  //删除右边节点的最小节点
            node.left = node.right = null;
            size--;
            return successor;
        }


    }

三、总结

二分搜索树的知识基本已经结束完,我们学习二分搜索树,我们主要是学了二分搜索树咋样插入一个元素,咋样查找一个元素,咋样去删除一个元素。咋样便利二分搜索树,分为前序中序后序便利。分别用递归和非 递归实现。然后讲解了,二分搜索树的层次便利。利用队列实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值