这是我参与「第三届青训营-后端场」笔记创作活动的的第11篇笔记。
经典排序算法
时间复杂度
| 最好 | 平均 | 最差 | |
|---|---|---|---|
| 插入排序 | O(n^2) | ||
| 快速排序 | |||
| 堆排序 |
实际 benchmark 结果
- 短序列和元素有序情况下,插入排序性能最好
- 大部分情况下,快速排序有较好的综合性能
- 几乎在任何情况下,堆排序的表现都比较稳定
pdqsort
pdqsort(pattern-defeating-quicksort) 是一种不稳定的混合排序算法,它的不同版本被应用在 C++ boost,Rust 以及 Go 1.19 中。它对常见序列类型做了特殊优化,使得在不同条件下都拥有不错的性能。
结合前面提到的三种排序方法,提出的优化方案:
- 对于短序列情况:使用插入排序
- 其它情况使用快速排序
- 优化 pivot 的选择:
- 中序列(<=50)采样三个元素,使用 meidan of three;
- 长序列(>50)采样九个元素,使用 median of median;
- 采样发现序列可能逆序,翻转序列;可能有序,使用有限插入排序
- 重复元素较多的情况(pivot 与上次相同时):使用 partitionEqual 将重复元素排列在一起
- 当 pivot 选择策略表现不佳时,随即交换元素
- 优化 pivot 的选择:
- 快速排序表现不佳(pivot离两端很近)达到一定次数时,切换到堆排序
| 最好 | 平均 | 最差 | |
|---|---|---|---|
| 插入排序 | O(n^2) | ||
| 快速排序 | |||
| 堆排序 | |||
| pdqsort |