平衡二叉树:从原理到实践的全面解析
在计算机科学中,树是一种至关重要的数据结构,而二叉树因其简洁性和高效性被广泛应用于查找、排序、索引等场景。然而,普通二叉树(如二叉搜索树,BST)在极端情况下会退化为“斜树”(所有节点仅存在左子树或右子树),此时其操作效率会从理想的O(log n)骤降至O(n),完全丧失了树形结构的优势。平衡二叉树(Balanced Binary Tree) 正是为解决这一问题而生——它通过一系列规则和操作维持树的高度平衡,确保无论输入数据如何,关键操作(插入、删除、查找)的时间复杂度始终保持在O(log n)级别。
本文将从二叉树基础出发,深入剖析平衡二叉树的定义、核心类型(AVL树、红黑树、B树等)、操作原理、应用场景及实现细节,帮助读者系统掌握这一数据结构的精髓。
目录#
- 二叉树基础:从BST到平衡的必要性
- 1.1 二叉树的定义与结构
- 1.2 二叉搜索树(BST)的特性与操作
- 1.3 BST的缺陷:不平衡的危害
- 平衡二叉树的定义与核心目标
- 2.1 平衡的标准:高度差限制
- 2.2 核心目标:维持O(log n)复杂度
- 常见平衡二叉树类型详解
- 3.1 AVL树:严格平衡的先驱
- 3.2 红黑树:实用主义的平衡策略
- 3.3 B树与B+树:多叉平衡树的崛起
- 3.4 其他平衡树简介(Splay树、Treap)
- 平衡二叉树的操作详解
- 4.1 查找操作:共性与差异
- 4.2 插入操作:平衡维护的核心场景
- 4.3 删除操作:最复杂的平衡挑战
- 应用场景与实践案例
- 5.1 AVL树:查找密集型场景
- 5.2 红黑树:高频插入/删除场景
- 5.3 B树/B+树:磁盘存储与数据库索引
- 不同平衡树的对比分析
- 实现示例:从零构建AVL树与红黑树
- 7.1 AVL树的Python实现
- 7.2 红黑树的核心代码片段
- 常见问题与调试技巧
- 未来发展与扩展
- 总结
- 参考文献
1. 二叉树基础:从BST到平衡的必要性#
1.1 二叉树的定义与结构#
二叉树是一种由节点组成的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的基本术语包括:
- 根节点(Root):树的顶层节点,无父节点;
- 叶子节点(Leaf):无子女的节点;
- 高度(Height):从节点到最远叶子节点的路径长度(空树高度为-1,单个节点高度为0);
- 深度(Depth):从根节点到该节点的路径长度(根节点深度为0)。
二叉树的形态多样,常见的有满二叉树(所有叶子节点在同一层,且非叶子节点均有两个子节点)、完全二叉树(除最后一层外,每一层均满,最后一层节点靠左排列)等。
1.2 二叉搜索树(BST)的特性与操作#
二叉搜索树(Binary Search Tree, BST) 是一种特殊的二叉树,其核心特性为:左子树所有节点的值 < 根节点的值 < 右子树所有节点的值(假设无重复值)。这一特性使得BST的查找操作可通过“二分”逻辑高效进行。
BST的基本操作:#
- 查找(Search):从根节点出发,若目标值小于当前节点值则向左子树递归,否则向右子树递归,直至找到或为空树。
- 插入(Insert):类似查找,找到目标位置(叶子节点的左/右子树)并插入新节点。
- 删除(Delete):分三种情况:
- 叶子节点:直接删除;
- 仅有一个子节点:用子节点替换待删节点;
- 有两个子节点:用中序后继(右子树最小节点)或中序前驱(左子树最大节点)替换待删节点,再删除后继/前驱。
BST的时间复杂度:#
理想情况下(树平衡),高度为h的BST有n≈2^h个节点,h≈log n,因此操作复杂度为O(log n)。
1.3 BST的缺陷:不平衡的危害#
BST的高效性依赖于平衡性,但普通BST对输入顺序敏感。例如,若输入序列为1, 2, 3, 4, 5,BST会退化为右斜树(每个节点仅有右子节点),此时树高h=n-1,操作复杂度退化为O(n)(与链表无异)。
示例:斜树的形成
插入序列 [1, 2, 3, 4, 5] 后,BST结构如下:
1
\
2
\
3
\
4
\
5
此时查找5需遍历5个节点,效率极低。
结论:为避免BST在动态数据(频繁插入/删除)中退化为斜树,必须引入平衡机制——这就是平衡二叉树的核心价值。
2. 平衡二叉树的定义与核心目标#
2.1 平衡的标准:高度差限制#
平衡二叉树的定义并非唯一,核心思想是通过限制左右子树的高度差来控制树的整体高度。常见的平衡标准包括:
- 严格平衡:左右子树高度差的绝对值 ≤ 1(如AVL树);
- 宽松平衡:通过其他规则间接限制高度(如红黑树通过颜色规则确保高度 ≤ 2log(n+1));
- 多叉平衡:允许节点有多个子节点,但限制树的整体高度(如B树、B+树)。
无论标准如何,最终目标都是将树高控制在O(log n)级别,确保操作效率。
2.2 核心目标:维持O(log n)复杂度#
平衡二叉树的设计目标可总结为:
- 高度控制:树高h = O(log n),其中n为节点数;
- 动态平衡:插入/删除操作后,通过局部调整(如旋转、 recoloring)恢复平衡,避免全局重构;
- 操作高效:平衡调整的额外开销尽可能小(如红黑树比AVL树旋转次数少)。
3. 常见平衡二叉树类型详解#
3.1 AVL树:严格平衡的先驱#
3.1.1 历史与定义#
AVL树由Adelson-Velsky和Landis于1962年提出,是首个自平衡BST。其平衡标准为:任意节点的左右子树高度差(平衡因子)的绝对值 ≤ 1。
平衡因子(Balance Factor, BF) 定义为:BF(node) = 左子树高度 - 右子树高度
,合法值为-1, 0, 1。
3.1.2 旋转操作:平衡恢复的核心#
当插入/删除导致节点BF超出[-1, 1]范围时,需通过旋转(Rotation) 操作调整树结构。旋转分为四种基本类型,本质是通过局部子树的“旋转”降低高度,恢复平衡。
(1)LL型(左左型)#
场景:节点的左子树高度 > 右子树高度+1,且左子树的左子树高度 ≥ 左子树的右子树高度。
调整:对节点执行右旋转(Right Rotation)。
示例:
z (BF=2) y (BF=0)
/ / \
y (BF=1) → x z (BF=0)
/
x (BF=0)
右旋转步骤:
- 将y的右子树设为z的左子树;
- 将z设为y的右子树;
- 更新z和y的高度。
(2)RR型(右右型)#
场景:节点的右子树高度 > 左子树高度+1,且右子树的右子树高度 ≥ 右子树的左子树高度。
调整:对节点执行左旋转(Left Rotation)(与LL型对称)。
(3)LR型(左右型)#
场景:节点的左子树高度 > 右子树高度+1,且左子树的右子树高度 > 左子树的左子树高度。
调整:先对左子树执行左旋转(转为LL型),再对节点执行右旋转。
示例:
z (BF=2) z (BF=2) y (BF=0)
/ / / \
y (BF=-1) → x (BF=1) → x z (BF=0)
\ /
x (BF=0) y (BF=0)
(4)RL型(右左型)#
场景:节点的右子树高度 > 左子树高度+1,且右子树的左子树高度 > 右子树的右子树高度。
调整:先对右子树执行右旋转(转为RR型),再对节点执行左旋转(与LR型对称)。
3.1.3 AVL树的插入与平衡维护#
插入步骤:
- 按BST规则插入新节点;
- 从新节点向上回溯,更新路径上所有节点的高度;
- 对BF绝对值>1的节点,根据类型(LL/RR/LR/RL)执行旋转,恢复平衡。
示例:插入序列 [30, 20, 10]
- 插入30(根节点,BF=0);
- 插入20(左子节点,30的BF=1,20的BF=0);
- 插入10(20的左子节点,20的BF=1,30的BF=2 → LL型);
- 对30执行右旋转,结果:
20 (BF=0)
/ \
10(BF=0) 30(BF=0)
3.1.4 AVL树的删除与平衡维护#
删除操作更复杂,因为删除可能导致多个节点BF失衡,需从待删节点父节点向上回溯,逐个检查并旋转。步骤为:
- 按BST规则删除节点;
- 从删除位置的父节点开始,向上更新各节点高度;
- 对BF绝对值>1的节点,执行旋转恢复平衡,继续向上检查(因旋转可能影响上层节点的BF)。
3.1.5 AVL树的性能分析#
- 高度:n个节点的AVL树高度h ≤ 1.44log(n+2)-1.328,接近理想的log n;
- 查找效率:O(log n)(严格平衡导致树高最小);
- 插入/删除效率:O(log n),但旋转次数较多(最坏情况O(log n)次旋转)。
3.2 红黑树:实用主义的平衡策略#
红黑树(Red-Black Tree)由Rudolf Bayer于1972年提出,后经Leo Guibas和Robert Sedgewick优化,是工业界应用最广泛的平衡树(如Java的TreeMap
、C++的std::map
、Linux内核的epoll
等)。其平衡标准比AVL宽松,通过颜色规则间接控制高度,以减少旋转次数。
3.2.1 红黑树的五大基本性质#
- 节点颜色:每个节点为红色或黑色;
- 根节点:根节点为黑色;
- 红色节点限制:红色节点的两个子节点必须为黑色(即“无连续红节点”);
- 黑色路径平衡:从任意节点到其所有叶子节点的路径中,黑色节点数量相同(称为“黑高”);
- 叶子节点:所有叶子节点(NIL节点,空指针)为黑色(简化边界条件处理)。
示例:一棵合法的红黑树
B(根, 黑高=2)
/ \
R R
/ \ / \
B B B B (叶子NIL节点)
3.2.2 红黑树的平衡保障#
上述性质确保了红黑树的高度h ≤ 2log(n+1)。证明思路:
- 设黑高为bh(根到叶子的黑色节点数,不含根),则路径至少有bh个黑色节点;
- 由性质3,红色节点不连续,故路径最多有bh个红色节点(红黑交替);
- 总高度h ≤ 2bh;
- 由性质4,n ≥ 2^bh - 1(满二叉树节点数),故bh ≤ log(n+1),h ≤ 2log(n+1)。
3.2.3 红黑树的插入操作#
插入的新节点默认设为红色(减少对黑色路径平衡的影响),插入后可能违反性质2(根为红)或性质3(连续红节点),需通过recoloring(重新着色) 和旋转修复。
插入修复的核心场景(设新节点为N,父节点为P,祖父节点为G,叔节点为U):#
- Case 1:U为红色 → 只需recolor(P和U改为黑色,G改为红色),然后以G为新节点继续向上检查;
- Case 2:U为黑色,且N为P的右子节点,P为G的左子节点 → 对P执行左旋转,转为Case 3;
- Case 3:U为黑色,且N为P的左子节点,P为G的左子节点 → P改为黑色,G改为红色,对G执行右旋转,修复完成。
示例:插入序列 [10, 20, 5, 15](初始根为10黑色)
- 插入20(红,父P=10黑,合法);
- 插入5(红,父P=10黑,合法);
- 插入15(红,父P=20红,G=10黑,U=5红 → Case 1):
- P=20和U=5改为黑色,G=10改为红色;
- G=10成为新根,违反性质2 → 将根强制改为黑色。
最终树结构:
B(10)
/ \
B(5) B(20)
/
R(15)
3.2.4 红黑树的删除操作#
删除操作更复杂,需处理“双重黑色”(删除黑色节点后,路径黑高减少,需补充黑色)。核心步骤:
- 按BST规则删除节点,标记“额外黑色”(若删除的是黑色节点);
- 通过recoloring和旋转消除“额外黑色”,恢复性质4。
删除修复涉及多达8种场景,但其核心思想与插入类似:通过局部调整(颜色+旋转)维持全局性质。
3.2.5 红黑树的性能分析#
- 高度:h ≤ 2log(n+1),略高于AVL树;
- 查找效率:O(log n),略低于AVL(因树高略大);
- 插入/删除效率:O(log n),旋转次数少(插入最多2次旋转,删除最多3次旋转),适合频繁动态操作。
3.3 B树与B+树:多叉平衡树的崛起#
B树(B-Tree)由R. Bayer和E. McCreight于1972年提出,是多叉平衡查找树,专为磁盘存储设计。其“多叉”特性减少了树的高度,从而降低磁盘I/O次数(磁盘访问成本远高于内存操作)。
3.3.1 B树的定义与性质#
一棵m阶B树(m≥2)满足:
- 每个节点最多有m-1个关键字(key)和m个子节点(child);
- 根节点至少有1个关键字,非根节点至少有⌈m/2⌉-1个关键字;
- 所有叶子节点在同一层(平衡的核心);
- 关键字按升序排列,且子节点指针指向的子树包含关键字范围。
示例:3阶B树(m=3,每个节点最多2个key,3个子节点)
[10, 30]
/ | \
[1,3] [15,20] [40,50] (叶子节点,同一层)
3.3.2 B树的插入与分裂#
插入关键字时,若节点关键字数达到m-1(满节点),则需分裂(Split):
- 插入新key后,节点关键字数为m;
- 以中间key为界,将节点分裂为左、右两个节点,中间key上升至父节点;
- 若父节点也满,则递归分裂。
3.3.3 B树的删除与合并#
删除关键字时,若节点关键字数低于⌈m/2⌉-1(下溢),需合并(Merge) 或旋转借调:
- 借调:从兄弟节点“借”一个key(通过父节点中转);
- 合并:若兄弟节点也无key可借,则与兄弟节点及父节点中的中间key合并为新节点。
3.3.4 B+树:B树的优化版本#
B+树是B树的变体,广泛用于数据库索引(如MySQL InnoDB),其改进点:
- 叶子节点:存储所有关键字,并按序连成链表(支持范围查询);
- 非叶子节点:仅存储关键字索引,不存储数据(减少索引层内存占用);
- 平衡性:所有叶子节点在同一层,查询效率稳定(O(log n))。
优势:范围查询无需回溯,直接遍历叶子链表;索引层更“瘦”,适合内存缓存。
3.4 其他平衡树简介#
(1)Splay树(伸展树)#
- 核心思想:不严格平衡,但通过“伸展操作”(将访问节点旋转至根)使频繁访问的节点靠近根,利用“局部性原理”优化性能;
- 应用:缓存系统、频繁访问的动态集合。
(2)Treap(树堆)#
- 核心思想:结合BST和堆的特性,每个节点包含key(满足BST)和优先级(满足堆),通过旋转维持堆性质,随机化优先级避免失衡;
- 优势:实现简单,期望时间复杂度O(log n)。
4. 平衡二叉树的操作详解#
4.1 查找操作:共性与差异#
所有平衡树的查找操作均基于BST的“二分”逻辑,时间复杂度取决于树高:
- AVL树:O(log n)(树高最小);
- 红黑树:O(log n)(树高略大,但实际差异可忽略);
- B树/B+树:O(log_m n)(m为阶数,树高极低,适合磁盘查找)。
4.2 插入操作:平衡维护的核心场景#
- AVL树:插入后需回溯检查BF,旋转次数较多(最坏O(log n)次);
- 红黑树:插入后最多2次旋转,recoloring成本低;
- B树:插入可能导致分裂(最坏O(log_m n)次分裂),但分裂是批量操作,适合磁盘。
4.3 删除操作:最复杂的平衡挑战#
- AVL树:删除后需回溯检查多个节点BF,旋转次数多;
- 红黑树:删除修复涉及“双重黑色”,但旋转次数最多3次;
- B树:删除可能导致下溢和合并,操作逻辑复杂,但效率稳定。
5. 应用场景与实践案例#
5.1 AVL树:查找密集型场景#
- 适用场景:静态或查找操作远多于插入/删除的场景(如字典查询);
- 案例:数据库中的静态索引、科学计算中的频繁查询表。
5.2 红黑树:高频插入/删除场景#
- 适用场景:动态数据集合,插入/删除频繁(如实时数据监控);
- 案例:
- Java
TreeMap
/TreeSet
(基于红黑树实现有序映射); - C++
std::map
/std::set
(底层红黑树); - Linux内核的
task_struct
(进程调度链表)。
- Java
5.3 B树/B+树:磁盘存储与数据库索引#
- 适用场景:海量数据存储(如数据库、文件系统),需减少I/O次数;
- 案例:
- MySQL InnoDB存储引擎(聚簇索引为B+树);
- 文件系统(NTFS、ext4的索引节点管理);
- MongoDB的索引结构。
6. 不同平衡树的对比分析#
特性 | AVL树 | 红黑树 | B树(m阶) | B+树(m阶) |
---|---|---|---|---|
平衡标准 | BF绝对值≤1 | 颜色规则+黑高平衡 | 叶子节点同层 | 叶子节点同层+链表 |
树高 | h≈1.44log n | h≈2log n | h≈log_m n | h≈log_m n |
查找效率 | O(log n)(最优) | O(log n)(次优) | O(log_m n) | O(log_m n) |
插入/删除旋转次数 | 多(O(log n)) | 少(插入≤2,删除≤3) | 分裂/合并(O(log_m n)) | 分裂/合并(O(log_m n)) |
空间开销 | 存储高度(int) | 存储颜色(1bit) | 多关键字+子节点指针 | 索引层仅存关键字 |
典型应用 | 查找密集型场景 | 动态数据集合 | 磁盘存储索引 | 数据库索引、范围查询 |
7. 实现示例:从零构建AVL树与红黑树#
7.1 AVL树的Python实现#
以下是AVL树的核心代码,包含节点定义、旋转、插入和查找:
class AVLNode:
def __init__(self, val):
self.val = val
self.left = None # 左子节点
self.right = None # 右子节点
self.height = 0 # 节点高度(默认0,空节点为-1)
class AVLTree:
def __init__(self):
self.root = None
# 获取节点高度(空节点返回-1)
def _get_height(self, node):
return node.height if node else -1
# 更新节点高度(基于子节点高度)
def _update_height(self, node):
node.height = 1 + max(
self._get_height(node.left),
self._get_height(node.right)
)
# 计算平衡因子
def _get_bf(self, node):
return self._get_height(node.left) - self._get_height(node.right) if node else 0
# 右旋转(LL型)
def _right_rotate(self, z):
y = z.left
T3 = y.right
# 旋转
y.right = z
z.left = T3
# 更新高度
self._update_height(z)
self._update_height(y)
return y # 新的根节点
# 左旋转(RR型)
def _left_rotate(self, z):
y = z.right
T2 = y.left
# 旋转
y.left = z
z.right = T2
# 更新高度
self._update_height(z)
self._update_height(y)
return y # 新的根节点
# 插入节点(递归实现)
def _insert(self, node, val):
# 1. 标准BST插入
if not node:
return AVLNode(val)
if val < node.val:
node.left = self._insert(node.left, val)
else:
node.right = self._insert(node.right, val)
# 2. 更新当前节点高度
self._update_height(node)
# 3. 计算平衡因子,检查是否失衡
bf = self._get_bf(node)
# 4. 失衡处理
# LL型:左左
if bf > 1 and val < node.left.val:
return self._right_rotate(node)
# RR型:右右
if bf < -1 and val > node.right.val:
return self._left_rotate(node)
# LR型:左右
if bf > 1 and val > node.left.val:
node.left = self._left_rotate(node.left)
return self._right_rotate(node)
# RL型:右左
if bf < -1 and val < node.right.val:
node.right = self._right_rotate(node.right)
return self._left_rotate(node)
# 未失衡,返回原节点
return node
# 对外插入接口
def insert(self, val):
self.root = self._insert(self.root, val)
# 查找节点(递归)
def search(self, val):
def _search(node):
if not node:
return False
if node.val == val:
return True
return _search(node.left) if val < node.val else _search(node.right)
return _search(self.root)
# 测试AVL树
avl = AVLTree()
for val in [30, 20, 10, 25, 40, 50]:
avl.insert(val)
print(avl.search(25)) # True
print(avl.search(60)) # False
7.2 红黑树的核心代码片段#
红黑树实现较复杂,以下是节点定义和插入修复的核心逻辑:
class RBNode:
RED = 0
BLACK = 1
def __init__(self, val):
self.val = val
self.color = RBNode.RED # 新节点默认红色
self.left = None
self.right = None
self.parent = None # 需父节点指针辅助旋转
class RBTree:
def __init__(self):
self.NIL = RBNode(None) # 哨兵节点(叶子节点)
self.NIL.color = RBNode.BLACK
self.root = self.NIL
# 左旋转(与AVL类似,需更新父节点指针)
def _left_rotate(self, x):
y = x.right
x.right = y.left
if y.left != self.NIL:
y.left.parent = x
y.parent = x.parent
if x.parent == self.NIL:
self.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y
# 插入修复(简化版,处理核心场景)
def _insert_fixup(self, z):
while z.parent.color == RBNode.RED: # 父节点为红,存在连续红节点
if z.parent == z.parent.parent.left: # 父节点是祖父左子
uncle = z.parent.parent.right
# Case 1: 叔节点为红 → 重着色
if uncle.color == RBNode.RED:
z.parent.color = RBNode.BLACK
uncle.color = RBNode.BLACK
z.parent.parent.color = RBNode.RED
z = z.parent.parent # 继续向上检查
else:
# Case 2: 叔节点为黑,且z是右子 → 转为Case 3
if z == z.parent.right:
z = z.parent
self._left_rotate(z)
# Case 3: 叔节点为黑,且z是左子 → 旋转+重着色
z.parent.color = RBNode.BLACK
z.parent.parent.color = RBNode.RED
self._right_rotate(z.parent.parent)
else: # 父节点是祖父右子,对称处理
... # 省略对称逻辑
self.root.color = RBNode.BLACK # 确保根为黑
# 插入操作
def insert(self, val):
z = RBNode(val)
z.left = self.NIL
z.right = self.NIL
# 1. 按BST规则插入
y = self.NIL
x = self.root
while x != self.NIL:
y = x
if z.val < x.val:
x = x.left
else:
x = x.right
z.parent = y
if y == self.NIL:
self.root = z
elif z.val < y.val:
y.left = z
else:
y.right = z
# 2. 修复红黑树性质
if z.parent == self.NIL:
z.color = RBNode.BLACK
else:
self._insert_fixup(z)
8. 常见问题与调试技巧#
8.1 旋转操作的理解难点#
- 误区:旋转仅改变节点位置,不改变BST性质(左<根<右);
- 技巧:画出现有树结构,标注BF或颜色,按步骤模拟旋转,重点关注节点的父/子指针更新。
8.2 删除节点后的平衡维护#
- 核心难点:AVL树需回溯多个节点,红黑树需处理“双重黑色”;
- 调试建议:插入/删除后,打印树的中序遍历(应有序)和高度/BF/颜色,验证是否符合平衡条件。
8.3 选择平衡树类型的原则#
- 优先考虑场景:查找多→AVL,插入/删除多→红黑树,磁盘存储→B+/B树;
- 避免过度设计:数据规模小或操作频率低时,普通BST或哈希表可能更简单高效。
9. 未来发展与扩展#
9.1 持久化平衡树#
- 定义:支持版本控制的平衡树,每次修改生成新版本而非覆盖旧版本;
- 应用:函数式编程、区块链(不可篡改数据)、版本控制系统。
9.2 并行平衡树#
- 挑战:传统平衡树依赖全局结构,难以并行化;
- 解决方案:无锁设计(如使用CAS原子操作)、分区锁(如只锁定修改的子树)。
9.3 混合结构优化#
- 示例:LSM树(Log-Structured Merge Tree)结合B+树和有序链表,优化写入性能(如LevelDB、RocksDB);
- 趋势:针对特定场景(如时序数据、地理数据)设计专用平衡树变体。
10. 总结#
平衡二叉树是解决普通BST失衡问题的关键技术,通过维持树的高度平衡,确保插入、删除、查找操作的时间复杂度稳定在O(log n)级别。本文系统介绍了三大核心类型:
- AVL树:严格平衡,查找效率最优,适合读多写少场景;
- 红黑树:宽松平衡,旋转次数少,适合动态数据集合;
- B树/B+树:多叉结构,树高极低,是磁盘存储和数据库索引的基石。
理解平衡树的核心在于掌握其平衡标准和调整机制(旋转、分裂、recoloring等),并根据应用场景选择合适的类型。无论是理论学习还是工程实践,平衡二叉树都是数据结构领域不可或缺的重要组成部分。
11. 参考文献#
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press.(第13章:红黑树;第18章:B树)
- Adelson-Velsky, G. M., & Landis, E. M. (1962). An algorithm for the organization of information. Doklady Akademii Nauk SSSR, 146, 263-266.(AVL树原始论文)
- Bayer, R. (1972). Symmetric binary B-trees: Data structure and maintenance algorithms. Acta Informatica, 1(4), 290-306.(B树原始论文)
- Wikipedia. "Balanced binary search tree". https://en.wikipedia.org/wiki/Balanced_binary_search_tree
- GeeksforGeeks. "AVL Tree | Set 1 (Insertion)". https://www.geeksforgeeks.org/avl-tree-set-1-insertion/