【Java高级数据结构】AVL树

AVL树

一棵AVL树或者是空树,或者是具有下列性质的二叉搜索树:

  • 它的左子树和右子树都是AVL树,
  • 且左子树和右子树的高度之差的绝对值不超过1。

在这里插入图片描述

结点的平衡因子 balance(balance factor)

  • 每个结点附加一个数字,给出该结点右子树的高度减去左子树的高度所得的高度差。这个数字即为结点的平衡因子 balance。
  • 根据AVL树的定义,任一结点的平衡因子只能取 -1、0、1。
  • 如果一个结点的平衡因子的绝对值大于1,则这棵二叉搜索树就失去了平衡,不再是AVL树。
  • 如果一棵二叉搜索树是高度平衡的,它就成为AVL树。如果它有 n 个结点,其高度可保持在 O(log2n),平均搜索长度也可保持在 O(log2n)。
AVL树结构设计
class AVLNode{
   
    private AVLNode leftChild;
    private AVLNode parent;
    private AVLNode rightChild;
    private int data;
    private int balance;
    public AVLNode(){
   
        leftChild = null;
        parent = null;
        rightChild = null;
        data = 0;
    }
    public AVLNode(int data){
   
        leftChild = null;
        parent = null;
        rightChild = null;
        this.data = data;
    }
    public AVLNode(int data,AVLNode parent){
   
        leftChild = null;
        this.parent = parent;
        rightChild = null;
        this.data = data;
    }
    public AVLNode(int data,AVLNode parent,AVLNode leftChild,AVLNode rightChild){
   
        this.leftChild = leftChild;
        this.parent = parent;
        this.rightChild = rightChild;
        this.data = data;
    }
}

private AVLNode head; //指向根节点
private int curSize; //记录有效个数
public AVLTree(){
   
    curSize = 0;
    head = new AVLNode();
}
平衡化旋转
  • 如果在一棵平衡的二叉搜索树中插入了一个新结点,造成了不平衡。此时必须调整树的结构,使之平衡化。
  • 平衡化旋转有两类:
    • 单旋转(左单旋和右单旋)
    • 双旋转(左平衡和右平衡)
  • 每插入一个新结点时,AVL树中相关结点的平衡状态会发生改变。因此,在插入一个新的结点后,需要从插入位置沿通向根结点的路径进行回溯,检查各结点的平衡因子(左、右子树的高度差)。
  • 如果在某一结点发现高度不平衡,停止回溯。
  • 从发生不平衡的结点起,沿刚才回溯的路径取直接下两层的结点。
  • 如果这三个结点处于一条直线上,则采用单旋转进行平衡化。单旋转可按其方向分为左单旋转和右单旋转,其中一个是另一个的镜像,其方向与不平衡的形状相关。
  • 如果这三个结点处于一条折线上,则采用双旋转进行平衡化。双旋转分为先左后右和先右后左两类。

在这里插入图片描述

左单旋转(RotateLeft)

在这里插入图片描述

  • 如果在子树E中插入一个新结点,该子树的高度增1导致结点A的平衡因子变成+2,出现不平衡。
  • 为使树恢复平衡,从A沿插入路径连续取3个结点A、C和E。它们处于一条方向为“\”的直线上,需要做左单旋转。
  • 以结点C为旋转轴,让结点A反时针旋转。

示例:

在这里插入图片描述

/**
 * 左单旋转
 * @param ptr
 */
private void
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值