Files
Data-Structure/BinaryTree/BalanceTree
2025-08-19 18:01:45 +08:00
..
2025-08-19 18:01:45 +08:00
2025-08-17 18:09:14 +08:00

好的!先从“平衡树”的共同目标说起,再分别讲 AVL、红黑树、B-Tree最后给一张对照表和选型建议。

什么是“平衡树”

“平衡树”都是在二叉搜索树BST或其多叉推广的框架上,通过限制高度来保证查找/插入/删除的时间复杂度稳定在 O(log n)。不同平衡树的“平衡标准”不同,越严格,高度越低(查找更快),但维护成本(旋转/分裂/合并)会更高。


AVL 树Adelson-Velsky and Landis

核心不变量

  • 对任一节点,|height(left) - height(right)| ≤ 1(平衡因子 ∈ {-1,0,+1})。
  • 通常在节点里存高度或平衡因子,插删后自底向上更新。

失衡与旋转

  • LL 型 → 右旋
  • RR 型 → 左旋
  • LR 型 → 先左旋子节点再右旋
  • RL 型 → 先右旋子节点再左旋

插入至多 1 次“单/双旋”(最多 2 次旋转);删除可能沿路径多处修复(最坏 O(log n) 次)。

复杂度与性质

  • 查找/插入/删除:O(log n)
  • 高度上界:约 ≈ 1.44 * log2(n)(非常低)
  • 优点:查找性能最稳定、树更矮
  • 缺点:更新更“敏感”,旋转相对多;实现需维护高度

适用

  • 查多改少或对最坏时延敏感的内存场景(如需要更低树高的索引、路由表等)

红黑树Red-Black Tree

核心不变量(颜色与黑高)

  1. 根为黑2) 叶子NIL为黑
  2. 红节点不能有红孩子(红红不相邻);
  3. 任一节点到其后代 NIL 的所有路径具有相同黑高

插删修复

  • 通过着色 + 旋转修复;
  • 插入:至多 2 次旋转;删除:至多 3 次旋转(但可能多次“上溯”重着色)。

复杂度与性质

  • 查找/插入/删除:O(log n)
  • 高度上界:≤ 2 * log2(n+1)(比 AVL 略高)
  • 优点:更新旋转次数少、实现成熟、工业广泛使用
  • 缺点:查找平均高度略高于 AVL

适用

  • 查改均衡的通用有序容器场景。C++ 的 std::map/std::set 通常用红黑树实现;大多数语言标准库的有序映射/集合也选择红黑树。

B-Tree多叉平衡搜索树

(数据库/文件系统的主角,常用的是 B+ 树变体)

结构

  • 每个节点可有最多 m 个孩子(多叉),节点里存有序键数组与孩子指针;
  • 所有叶子在同一层
  • 除根外:每个节点的键数在 [ceil(m/2)-1, m-1] 之间(保证“半满”)。

为何快(外存友好)

  • 把一个节点的键打包成一页(如 4KB,一次 I/O 读入很多键;
  • 分支因子大(几百级),高度极低,因此磁盘/SSD 的随机 I/O 次数很少。
  • 复杂度常写作 O(log_m n)以分支因子为底I/O 次数非常小。

插入/删除

  • 插入:若目标节点满则分裂(把中间键上推给父节点),可能层层上推到根,根也满则新建根,高度+1
  • 删除:若节点“欠满”,先向兄弟借键,不行再合并,可能向上连锁。

B+ 与 B*

  • B+ 树:所有数据都在叶子,内节点只存键;叶子链表天然支持范围扫描与顺序遍历(数据库最常见)。
  • B*:更激进的“借/并”策略,节点利用率更高(≥ 2/3 满),进一步减少高度与 I/O。

适用

  • 磁盘/SSD 上的大规模索引:数据库(如 InnoDB 使用 B+ 树、文件系统、KV 存储等。
  • 内存里也可用,但优势主要在外存局部性与范围扫描。

对照速览

维度 AVL 红黑树 B-Tree / B+
结构 二叉 二叉(带颜色) 多叉(分支因子大)
平衡标准 每节点左右高差 ≤ 1 黑高相等、红红不相邻 节点半满,叶子同层
高度 最矮(≈ 1.44 log₂ n 略高(≤ 2 log₂ n 极矮logₘ n
查找 最稳定 稍逊于 AVL 节点内二分后 I/O 极少
插入/删除 旋转较多 旋转较少 + 着色 分裂/合并,页级操作
范围扫描 最好B+ 叶子链)
典型场景 内存、查多改少 通用有序容器 外存索引/数据库

什么时候选谁?

  • 内存、查多改少、追求极低高度 → 选 AVL
  • 内存、查改都多、工程通用与易用性 → 选 红黑树(标准库同款)。
  • 磁盘/SSD、大数据、范围查询 → 选 B+ 树 / B-Tree(页友好,极少 I/O

如果你愿意,我可以再给你:

  1. AVL 和红黑树的旋转小抄(带 4 种失衡示意);
  2. B+ 树节点尺寸推算(给定页大小、键宽/指针宽,估算分支因子与高度);
  3. 一段C++ 伪代码/最小实现骨架帮助你在题目里自写平衡树。