平衡二叉查找树的删除及删除调整

本文详细介绍了AVL树的删除过程,包括四种删除情况的处理:删除结点的左右子树都为空、左子树为空、右子树为空、左右子树都不为空。删除后,通过回溯调整平衡因子,根据失衡情况执行相应的旋转操作,确保AVL树的平衡。同时,文章提到了平衡调整的细节,分析了左右失衡时的不同处理策略,并提供了源代码作为参考。
摘要由CSDN通过智能技术生成

AVL树的删除

   avl树的删除,我们需要从某一个角度或者视角去想问题,比如我们根据删除的结点的继承关系来看:

        1.删除的结点 左右子树都为空

            (1)可能是根节点,那么我们直接删掉他

            (2)可能是叶子结点,在删除时我们认为它被删除,然后以它为基点回溯调整树,最后删掉它。

        2.删除的结点 左子树为空 , 右子树不为空

            由于avl树删除之前是平衡的,左子树为空,右子树不能超过1个结点。那么我们以右子树唯一一个的结点为后继,把他的值替换给待删除结点,我们认为后继节点被删除了,以后继节点为基点回溯。

        3.删除的结点 右子树为空 , 左子树不为空

            由于avl树删除之前是平衡的,右子树为空,左子树上不能超过1个结点。那么我们以左子树唯一一个结点为前驱,把他的值替换给待删除结点,我们认为前驱结点被删除了,以前驱结点为基点回溯。

        4.删除的结点 左右子树都不为空

            删除结点的左右子树都不为空,因为只能找一个结点替换值,那么我们以找后继为先,左右子树都不为空就一定可以找到后继节点,但是,因为左右子树都不为空,后继结点可能会有右子树(因为后继结点一定不会有左子树),当然也可能不会有右子树。那么我们先把后继节点值赋值给待删结点,此时 我们需要把后继结点删除,焦点被引向了后继结点。

         待删除的对象 变成了 后继结点,后继节点一定没有左子树,那么就转换到了上面的情况2,待删除的结点左子树为空,右子树不为空的情况。

删除之后的调整

   首先,删除不一定需要调整,删除后首先是以基点进行回溯,维护平衡因子值,删除的结点是左子树那么根节点值要+1,如果删除结点是右子树那么根节点值要-1,根节点原来为0,+-1之后不发生平衡改变,但是根节点原来为±1,+-1之后就可能会有变成±2的情况。这时候我们需要根据失衡结点的平衡因子值来去判断哪个方向失衡了。

    备注:最下方我会把插入的代码也粘贴上,如不想打开插入解析的博文,根据代码也能看出之前一些变化的操作。

    如果左边失衡,也就是失衡节点(unbalance)平衡因子值为2,根据失衡结点的左孩子(unbLChild)的平衡因子的值不同就会产生以下三种情况:

    1.unbLChild = 1 左左失衡,与插入时一样,我们调整unbalance和unbLChild的平衡因子等于 0,以unbalance为基点右旋转即可。

    2.unbLChild = -1 左右失衡,  与插入一样 ,根据unbLChild的右孩子的平衡因子值分为三种情况。(这里就不继续描述了)

    3.unbLChild = 0  左失衡unbLChild的平衡因子值为0 ,根据平衡因子为0的视角来看:

        一种情况是unbLChild是叶子结点。一种情况是,unbLChild有左右子树,左右子树平衡。

        首先来看第一种:unbLChild是叶子结点。

            分析:unbLChild是叶子结点,那么失衡节点左子树只有一个结点,不会发生左失衡,所以不存在unbLChild是叶子结点的情况。

        再来看第二种:unbLChild左右子树平衡,我们需要右旋转,但是右旋转过后,树2会成为120的左子树,而树2比树3高1,所以 120 平衡因子要先被设定为 1 ,unbLChild变成了根结点,那么 树1 比 树2+1 少1,所以unbLChild平衡因子要被设置为-1。这样旋转之后平衡了,平衡因子也正确了。

    如果右边失衡,也就是失衡节点(unbalance)平衡因子值为-2,根据失衡结点的左孩子(unbRChild)的平衡因子的值不同就会产生以下三种情况:

    1.unbRChild = -1右右失衡,和插入时一样的操作,右右失衡一次左旋就OK,平衡因子和插入也是一样的调整。

    2.unbRChild = 1右左失衡,和插入时一养的操作,右左失衡先右旋再左旋,平衡因子和插入也是一样的调整。

    3.unbRChild = 0 右失衡unbRChild的平衡因子值为0 。unbRChild的左右子树平衡,unbalance右失衡,左旋。由于左旋后树1变成120的右孩子,树1 - 树3 = 1,所以120的平衡因子要改为-1 ,树1变为右孩子,180变成根结点那么,180左子树为120  , 右子树为树2 ,120比树2高1,所以180平衡因子应改为1。旋转后就平衡了。

源代码

public class AVLTree<E extends Comparable> {

    public AVLNode<E> treeRoot = null;

    private static final int LH = 1;    //左子树 - 右子树 = 1     左高
    private static final int EH = 0;    //左子树 - 右子树 = 0     左右子树同高
    private static final int RH = -1;   //左子树 - 右子树 = -1    右高


    /**
     * 插入值
     * @param data
     * @return
     */
    public boolean insertAVL(E data){
        try {
            if(data == null) return false;
            System.out.println("提示:插入的数据为:" + data + "  2秒后开始插入!");
            Thread.sleep(10);
            return insertAVL(new AVLNode<E>(data));
        } catch (InterruptedException e) {
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值