Files
Data-Structure/Data-Structure/BinaryTree/BalanceTree/README.MD
2025-08-28 21:17:28 +08:00

124 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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