Java进阶:17.2 AVL树

1、AVL树(平衡二叉树BBST):

AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为 平衡二叉树。下面是平衡二叉树和非平衡二叉树对比的例图:
在这里插入图片描述

平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;

AVL = 适度平衡:对于高度为h的AVL树,至少包含S(h) = fib(h+3) -1 个节点。即有 S(h) = 1 + S(h-1) + S(h-2)

2、AVL树的作用

对于一般的二叉搜索树,其期望高度(即为一棵平衡树时)为log2N,其各操作的时间复杂度(O(log2n))同时也由此而决定。但是,在某些极端的情况下(如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n)。我们可以通过随机化建立二叉搜索树来尽量的避免这种情况,但是在进行了多次的操作之后,由于在删除时,我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。这同时也会造成树的平衡 性受到破坏,提高它的操作的时间复杂度。

例如:我们按顺序将一组数据1.2.3.5.10.20分别插入到一颗空二叉查找树和AVL树中,插入的结果如下图:
在这里插入图片描述
  由上图可知,同样的结点,由于插入方式不同导致树的高度也有所不同。特别是在带插入结点个数很多且正序的情况下,会导致二叉树的高度是O(N),而AVL树就不会出现这种情况,树的高度始终是O(lgN).高度越小,对树的一些基本操作的时间复杂度就会越小。这也就是我们引入AVL树的原因

3、AVL树的基本操作

AVL树的操作基本和二叉查找树一样,这里我们关注的是两个变化很大的操作:插入和删除!
在AVL树中刚插入一个节点后失衡节点个数最多为O(lgn)
在AVL树中刚删除一个节点后失衡节点个数最多为O(1)
我们知道,AVL树不仅是一颗二叉查找树,它还有其他的性质。如果我们按照一般的二叉查找树的插入方式可能会破坏AVL树的平衡性。同理,在删除的时候也有可能会破坏树的平衡性,所以我们要做一些特殊的处理,包括:单旋转和双旋转!
对于必须重新平衡的节点a,不平衡主要出现在以下4种情况中:

  1. 对a的左儿子的左子树进行一次插入 (1和4镜像对称)
  2. 对a的左儿子的右子树进行一次插入 (2和3镜像对称)
  3. 对a的右儿子的左子树进行一次插入
  4. 对a的右儿子的右子树进行一次插入
    在这里插入图片描述
    对插入操作的平衡有两种方法:单旋、双旋
    在这里插入图片描述

AVL树的插入,双旋转的第一种情况—左右(先左后右)旋:
在这里插入图片描述
由上图可知,我们在T结点的左结点的右子树上插入一个元素时,会使得根为T的树的左右子树高度差的绝对值不再 < 1,如果只是进行简单的右旋,得到的树仍然是不平衡的。我们应该按照如下图所示进行二次旋转:
  在这里插入图片描述
左右情况的左右旋转实例:
在这里插入图片描述

AVL树的插入,双旋转的第二种情况—右左(先右后左)旋:
在这里插入图片描述
  由上图可知,我们在T结点的右结点的左子树上插入一个元素时,会使得根为T的树的左右子树高度差的绝对值不再 < 1,如果只是进行简单的左旋,得到的树仍然是不平衡的。我们应该按照如下图所示进行二次旋转:
在这里插入图片描述
  右左情况的右左旋转实例:在这里插入图片描述

4、AVL树评价

优点:无论查找、插入或者删除,最坏情况下的复杂度均为O(logn),O(n)的存储空间
缺点:
借助高度或者平衡因子,需要改造元素结构,或额外封装
实测复杂度与理论值尚有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值