Balance Tree

This commit is contained in:
e2hang
2025-08-17 18:09:14 +08:00
parent 1e555261e5
commit a838daf577
2 changed files with 123 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
好的!先从“平衡树”的共同目标说起,再分别讲 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++ 伪代码/最小实现骨架**帮助你在题目里自写平衡树。