| 项目 | 值 |
|---|---|
| 主题 | 外部排序的败者树 |
| 核心概念 | 多路归并中,用败者树在 k 个段当前元素里快速选最小值 |
| 时间复杂度 | $O(\log_2 k)$ |
| 稳定性 | 稳定 |
| 难度 | ⭐⭐⭐⭐ |
当数据量太大无法全部装入内存时,需要使用外部排序。最常用的外部排序方法是多路归并排序。
在 k 路归并中,需要从 k 个归并段的当前元素中选出最小值。
败者树是一棵完全二叉树,用于在 k 个元素中快速找到最小值。
对于 k 路归并,败者树有:
总共 2k 个节点(或 $k + (k-1) + 1 = 2k$)。
当一个叶子节点的值被更新后(即该归并段读入下一个元素),需要:
时间复杂度:$O(\log_2 k)$
题目:4 个归并段的当前元素为:段1→3,段2→5,段3→2,段4→7。
叶子节点(从左到右):段1=3,段2=5,段3=2,段4=7。
自下而上调整:
败者树:
[0] → 段3 (最终胜者, 值=2)
/
[2] → 败者=段1 (值=3)
/ \
[1] [3]
败者=段2 败者=段4
(值=5) (值=7)
/ \ / \
段1 段2 段3 段4
3 5 2 7
题目:接上例,输出段3的元素 2 后,段3读入下一个元素 8,调整败者树。
输出:3(来自段1)。比较次数:2 次 $= \log_2 4 = 2$。
题目:8 路归并,用败者树选出一个最小元素需要多少次比较?
答:$\lceil\log_2 8\rceil =$ 3 次,而朴素方法需要 7 次($8-1$)。
| 概念 | 公式 / 值 |
|---|---|
| k 路归并选出最小值(败者树) | $\lceil\log_2 k\rceil$ 次比较 |
| k 路归并选出最小值(朴素) | $k-1$ 次比较 |
| 败者树节点数 | $2k-1$(k 叶 + k-1 内部) |
| 调整时间复杂度 | $O(\log_2 k)$ |
| 败者树优势 | 更新时只沿路径向上比较 |
(暂无关联知识点)