| 数据特征 | 推荐算法 | 原因 |
|---|---|---|
| 数据量小 $(n\leq50)$ | 直接插入 | 常数因子小,简单高效 |
| 数据量大 | 快速 / 归并 / 堆 | $O(n\log n)$ |
| 基本有序 | 直接插入 | 最好 $O(n)$ |
| 逆序程度大 | 快速 / 归并 / 堆 | 不依赖初始序列 |
| 关键字范围小 | 计数 / 基数排序 | $O(n)$ 或 $O(d\cdot n)$ |
问题:从 $n$ 个元素中找出最大(或最小)的 $k$ 个。
| 方法 | 时间 | 适用场景 |
|---|---|---|
| 排序后取前 $k$ 个 | $O(n\log n)$ | 需要完整排序 |
| 建堆取 $k$ 次堆顶 | $O(n+k\log n)$ | $k$ 较小 |
| 快速选择算法 | $O(n)$ 平均 | 只需要第 $k$ 大 |
| 小根堆维护 $k$ 个元素 | $O(n\log k)$ | $k$ 较小,流式数据 |
实际排序库(C++ STL sort、Java Arrays.sort)采用混合策略:
数据量超过内存时用外部排序:
| 应用场景 | 最优策略 | 时间 |
|---|---|---|
| Top-K($k$ 小) | 堆 | $O(n\log k)$ |
| Top-K($k$ 大) | 排序取前 $k$ | $O(n\log n)$ |
| 第 $k$ 大 | 快速选择 | $O(n)$ 平均 |
| 中位数 | 快速选择 | $O(n)$ 平均 |
| 数据去重 | 排序后扫描 | $O(n\log n)$ |
| 区间合并 | 排序后扫描 | $O(n\log n)$ |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。