【数据结构】考研数据结构核心考点:平衡二叉树(AVL树)详解——平衡因子与4大旋转操作入门指南

平衡二叉树

导读

大家好,很高兴又和大家见面啦!!!

在上一篇内容中,我们深入探讨了​​二叉排序树()​​,了解了它如何通过 ​​"左子树 < 根结点 < 右子树 "​​ 的简单规则实现动态集合的高效查找、插入和删除 。其查询性能理想情况下可以达到优秀的 O ( log ⁡ n ) O(\log n) O(logn)。

然而,我们也留下了一个关键的悬念:​​当插入的序列接近有序时 ,二叉排序树会退化成一条"链" ,搜索性能会急剧下降至 O ( n ) O(n) O(n),这与线性表无异,完全丧失了树形结构的优势。
1 2 3 5 6 7 4 1 NULL 2 NULL 3 NULL 4 NULL 5 NULL 6 NULL 7 NULL NULL

​​

那么,我们能否创造一种​​能够"自我约束 "、始终保持良好身材​​的二叉排序树呢?答案是肯定的!

今天,我们就来揭开​​平衡二叉树()​​ 的神秘面纱。它正是为了解决 的"退化"问题而诞生的。​​ 在 的基础上增加了一条简单的"军规":

  • 任意结点的左右子树高度差不能超过 1 1 1

这条规则看似简单,却蕴含着巨大的能量,它能确保整棵树始终维持着"完美"或"接近完美"的平衡,从而将最坏情况下的时间复杂度牢牢锁定在 ​​ O ( log ⁡ n ) O(\log n) O(logn)​​。

在本篇中,我们将一起学习:

  • 是如何通过平衡因子来监控自身平衡状态的。
  • 理解"最小不平衡子树" 这一关键概念,它是我们进行修复的精确目标。
  • 初步认识当平衡被打破时, 赖以维持平衡的四大"旋转"秘籍LL, RR, LR, RL)。

现在,就让我们正式开始,探索这种兼具 的灵活性与稳定高效查询性能的优雅数据结构吧!

一、基本定义

为了避免树的高度增长过快,降低二叉排序树的性能,规定在插入和删除结点时,要保证任意结点的左、右子树高度差的绝对值不超过1,将这样的二叉树称为平衡二叉树Balanced Binary Tree ),也称 。

:这个名字的全称为:Adelson-Velsky and Landis Tree (/ˈædəlsən ˈvelski ənd ˈlændɪs triː/)。G.M. Adelson-Velsky ​​ 和 ​​E.M. Landis 这两位发明者于1962年的论文中提出该数据结构,因此该数据结构也由这两位提出者的名字命名。

定义结点左子树与右子树的高度差为该结点的平衡因子 ,则二叉树结点的平衡因子的值只可能是 − 1 、 0 、 1 -1、0、1 −1、0、1 这三个值中的一种。

因此平衡二叉树可定义为一棵空树,或是具有以下性质的二叉树:

  • 左子树与右子树均为平衡二叉树
  • 左子树与右子树的高度差的绝对值不超过1

若我们将各结点的平衡因子存储在各结点中,那么二叉树是否平衡可以体现为以下情况:

  • 平衡二叉树

a
1 b
-1 c
1 d
0 e
1 f
0 NULL g
0 NULL

在上述的这棵二叉树中,总共7个结点:

  • 结点a:
    • 左子树高度为 3 3 3
    • 右子树高度为 2 2 2
    • 平衡因子:左子树 - 右子树 = 3 − 2 = 1 3 - 2 = 1 3−2=1
  • 结点b:
    • 左子树高度为 1 1 1
    • 右子树高度为 2 2 2
    • 平衡因子:左子树 - 右子树 = 1 − 2 = − 1 1 - 2 = -1 1−2=−1
  • 结点d:
    • 左子树高度为 0 0 0
    • 右子树高度为 0 0 0
    • 平衡因子:左子树 - 右子树 = 0 − 0 = 0 0 - 0 = 0 0−0=0

可以看到,这棵二叉树的任意一棵子树均为平衡二叉树,且其左右子树的高度差的绝对值也不超过1,因此这棵树为一棵平衡二叉树

  • 不平衡二叉树

a
2 b
-1 c
0 d
0 e
0 f
0 g
0

在上述这棵二叉树中,同样有7个结点

  • 结点a:
    • 左子树高度为: 3 3 3
    • 右子树高度为: 1 1 1
    • 平衡因子:左子树 - 右子树 = 3 − 1 = 2 3 - 1 = 2 3−1=2
  • 结点b:
    • 左子树高度为: 1 1 1
    • 右子树高度为: 2 2 2
    • 平衡因子:左子树 - 右子树 = 1 − 2 = − 1 1 - 2 = -1 1−2=−1
  • 结点e:
    • 左子树高度为: 1 1 1
    • 右子树高度为: 1 1 1
    • 平衡因子:左子树 - 右子树 = 1 − 1 = 0 1 - 1 = 0 1−1=0

可以看到虽然该棵树的左右子树均为平衡二叉树,但是其左右子树的高度差的绝对值却大于1,因此该棵树不是一棵平衡二叉树

二、 的插入

二叉排序树保证平衡的基本思想如下:

  • 每当在二叉排序树中插入(或删除)一个结点时,首先检查其插入路径上的结点是否因此次操作而导致了不平衡。
  • 若导致了不平衡,则先找到插入路径上离插入结点最近的平衡因子的绝对值大于1的结点 a
  • 再对以结点 a 为根的子树,在保持二叉排序树特性的前提下,调整各个结点的位置关系,使其重新达到平衡

下面我们通过一个实例来理解该保持平衡的思想;
27
-1 16
0 75
1 38
0 NULL

在上述这棵 中,第一行是结点中存储的关键字的值,第二行是该结点所在的子树对应的平衡因子。

接下来我们需要在树中插入一个元素: 51 51 51 。根据二叉排序树的插入规则,我们会得到下面这棵 :
27
-2 16
0 75
2 38
-1 NULL NULL 51
0

可以看到,此时的 中,有两棵子树的平衡因子的绝对值大于 1 1 1 ,其对应的子树分别为:

  • 关键字: 27 27 27 为根结点的子树

27
-2 16
0 75
2 38
-1 NULL NULL 51
0

  • 关键字: 75 75 75 为根结点的子树

75
2 38
-1 NULL NULL 51
0

按照二叉排序树保证平衡的基本思想,我们需要找到 离插入结点最近的不平衡子树最小不平衡子树 ),也就是上图中以 75 75 75 为根结点的子树;再通过调整该子树中的结点位置,来使其重新达到平衡(具体的调整过程这里我们不展开说明,我们现在只关心最后的调整结果):
75
0 38
0 51
0

上图所示的这棵子树就是我们说的 最小不平衡子树

当我们完成对该子树的调整后,整棵二叉排序树就被调整为了下面这棵新的 :
27
-1 16
0 75
0 38
0 51
0

可以看到,此时的 又恢复成了一棵 。

PS: 像这种能够将自身自动调整为 的 我们也将其称为 自平衡二叉排序树 (Self-Balancing Binary Search Tree , SBBST)

在 的插入过程中,从空树开始,前半部分的插入与 的插入过程一致,都是通过 左子树 < 根结点 < 右子树 的规则进行新结点的插入。

这里有不太清楚的朋友可以回顾上一篇内容:【数据结构】考研数据结构核心考点:二叉排序树()全方位详解与代码实现 这里我就不再继续展开赘述。

当出现了某个结点插入后,导致整棵树失去平衡时,则需要做出相应的调整。具体的调整规则可以归纳为以下4种:

  • LL平衡旋转------最小不平衡子树的根结点的左孩子向右旋转1次
  • RR平衡旋转------最小不平衡子树的根结点的右孩子向左选择1次
  • LR平衡旋转------最小不平衡子树的根结点的左孩子的右孩子先向左选择1次,再向右旋转1次
  • RL平衡旋转------最小不平衡子树的根结点的右孩子的左孩子先向右旋转1次,再向左选择1次

具体我们应该如何判断失衡的 是属于那种调整规则?并且在不同的规则下我们又应该如何调整呢?具体内容,我们将会在下一篇章中详细介绍。

结语

今天的内容到这里就全部结束了。我们来简单回顾一下本次的核心旅程:

我们从一个关键问题出发------普通的二叉排序树 () 在极端情况下会退化成链表,导致性能骤降

而 ,正是为了解决这一痛点而生的优雅解决方案。它通过引入 平衡因子 这一精妙的"仪表盘",并立下"左右子树高度差绝对值不超过1 "的铁律 ,成功地实现了自我约束

我们深入理解了:

  • 基本定义:明确了是带有平衡约束的二叉排序树

  • 核心思想:掌握了插入结点后,如何通过寻找 最小不平衡子树 来定位问题根源。

  • 解决框架:认识了让 具体的调整过程这里我们不展开说明,我们现在只关心最后的调整结果 恢复平衡的四大 "秘籍 "------LL, RR, LR, RL 旋转

然而,故事才刚刚开始!我们知道了有四大 "武功秘籍 "可以"拨乱反正 ",但最关键的一步还悬而未决

  • 面对一棵刚刚失衡的AVL树,我们究竟该如何一眼诊断出它属于哪种失衡类型
  • 每一种旋转的具体操作步骤又是怎样的?

这些看似复杂的旋转操作,背后其实隐藏着一条可以轻松驾驭的、统一的逻辑链。 掌握了它,你就能在眨眼间判断出应对策略。

这一切的答案,以及完整的代码实现,都将在下一篇内容中为你彻底揭晓!

感谢阅读,欢迎用以下方式支持继续创作

👍 点赞支持 - 您的认可,是我持续创作清晰易懂教程的最大动力!

⭐ 收藏文章 - 将这篇 核心框架指南收藏起来,方便日后随时查阅,为下一篇深入理解旋转操作打下坚实基础。

🔁 转发分享 - 如果您有朋友也在学习数据结构,欢迎推荐给TA,大家一起进步。

💬 评论交流 - 关于平衡因子或最小不平衡子树,您还有哪些疑问?最期待下篇详解哪种旋转?欢迎在评论区留言!

感谢各位的支持,我们下一篇,不见不散!

*[BST]: Binary Search Tree,二叉搜索树/二叉排序树
*[AVL树]: Adelson-Velsky and Landis Tree,自平衡二叉排序树

相关推荐
andwhataboutit?4 小时前
Docker Compose学习
学习·docker·容器
郭庆汝4 小时前
自然语言处理笔记
笔记·自然语言处理·easyui
二进制怪兽4 小时前
[笔记] 驱动开发:Virtual-Display-Driver编译过程
笔记
ouliten4 小时前
cuda编程笔记(28)-- cudaMemcpyPeer 与 P2P 访问机制
笔记·cuda
im_AMBER4 小时前
数据结构 04 栈和队列
数据结构·笔记·学习
尘似鹤4 小时前
微信小程序学习(六)--多媒体操作
学习·微信小程序·小程序
要做朋鱼燕5 小时前
密码学安全:CIA三元组与三大核心技术
网络·笔记·密码学·嵌入式·加密·aes
UpYoung!5 小时前
无广技术贴!【PDF编辑器】Solid Converter PDF保姆级图文下载安装指南——实用推荐之PDF编辑软件
学习·数学建模·pdf·编辑器·运维开发·个人开发
金水谣5 小时前
考研10.5笔记
笔记