diff --git a/BinaryTree/BalanceTree/AVLTree/AVLTree的4中旋转方式.pdf b/BinaryTree/BalanceTree/AVLTree/AVLTree的4中旋转方式.pdf new file mode 100644 index 0000000..05c78fb Binary files /dev/null and b/BinaryTree/BalanceTree/AVLTree/AVLTree的4中旋转方式.pdf differ diff --git a/BinaryTree/BalanceTree/README.MD b/BinaryTree/BalanceTree/README.MD new file mode 100644 index 0000000..271c771 --- /dev/null +++ b/BinaryTree/BalanceTree/README.MD @@ -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++ 伪代码/最小实现骨架**帮助你在题目里自写平衡树。