平衡二叉树建立,平衡二叉树的平衡、删除

本文详细介绍了平衡二叉树(如AVL树)的建立过程、如何找到并调整最小不平衡子树,包括左左、右右、左右、右左四种失衡情况的处理方法。此外,还讨论了在插入和删除节点时如何维护平衡,并提供了一种判断不平衡状态的思路。

重要参考:平衡二叉树(解惑)
平衡二叉树的java实现

平衡二叉树建立

static class Node{
        Node parent;
        Node leftChild;
        Node rightChild;
        int val;
        public Node(Node parent, Node leftChild, Node rightChild,int val) {
            super();
            this.parent = parent;
            this.leftChild = leftChild;
            this.rightChild = rightChild;
            this.val = val;
        }
        
        public Node(int val){
            this(null,null,null,val);
        }
        
        public Node(Node node,int val){
            this(node,null,null,val);
        }

    }

调整平衡二叉树

平衡二叉树AVL(平衡二叉树是一种特殊的二叉搜索树)失衡,分为左左(指在一个节点的左孩子的左孩子上插入节点(无论插得是左还是右节点)使二叉树失衡,就叫左左)、右右、左右、右左
调整平衡二叉树,可以通过“旋转”,但是首先必须明白一个核心操作,不让它叫“旋转”!而叫——>“两个结点的变换”

  • 左左(右右)

    • 只需一次变换,交换第一个不平衡的结点它左(右)孩子的节点,若左(右)孩子有子节点,根据大小情况调整
      在这里插入图片描述
  • 左右

    • 稍微复杂了点,需要进行两次交换,才能达到平衡,先交换第一个不平衡节点的左孩子这个左孩子的右孩子节点,然后交换 交换后的第一个不平衡节点它的左孩子
      在这里插入图片描述
  • 右左

    • 交换第一个不平衡节点的右孩子这个右孩子的左孩子节点,然后交换 交换后的第一个不平衡节点它的右孩子

在这里插入图片描述

  • 一定要注意这个交换操作,比如a与b交换(a在上,b在下),b一定要占据a的位置!什么意思?就是b要放在(覆盖)储存a的那块内存上,

如何找到最小不平衡子树的根结点x,并判断出它是属于那种情况的?

  • 插入一个结点时,我们首先找到需要插入的位置,并插入;数据结构上用的是递归

  • 显然插入之后就要检查是否出现不平衡的结点

    • 那么如何检查?
      我们知道,你插入的时候用的是递归,一条线找到要插的位置,并插入;那么谁的平衡因子的有可能变呢? 不难想象,只有该条线上的结点的平衡因子有可能改变!那么我们在回溯的时候不就可以找到第一个不平衡的子树的结点?!

    • 可是我们如何判断该结点的平衡因子是否改变
      显然要看它被插入结点的一边的深度是否增加

    • 如何看它被插入结点的一边的深度是否增加?
      在这里插入图片描述
      如上图,如何看x的右孩子a(即被插入结点的一边)的深度增加?我们知道在a的右孩子上插入了结点y那么a的bf是一定要减1。那么x结点的bf可根据a的bf决定是否改变

      若a:bf变为-1或1,那么a之前一定为0,表示a的深度增加了,那么x的bf可根据a是x哪一边的孩子决定+1或-1

      若a:bf变为0,那么a之前一定为-1或1,表示a的深度每增加,那么不仅x的bf就不用变,该条线上的所有结点的bf都不用变,直接返回即可

找到最小不平衡子树的根结点x了,如何判断它属于哪种不平衡呢?

没看懂,不过我觉得应该可以定义一个函数,专门用来判断属于哪种不平衡,在做插入删除操作后进行判断

删除节点(与二叉排序树删除方法相同,就是加入了平衡调整)

如果左右子树都非空。在高度较大的子树中实施删除操作

  • p为叶子节点,直接删除
  • p只有一个子节点,将p删除掉后,将p的子节点代替p的位置
  • p既有左子树也有右子树
    • 先沿着p的左(右)子树右(左)子节点一直往右(左)走,直到来到其右(左)子树的最右(左)边的一个节点r,然后将p中的关键字用r中的关键字代替,最后判断r是否为叶子节点,然后用上面两个方法处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值