从零开始打造 pdqsort|青训营笔记

64 阅读1分钟

3.从零开始打造 pdqsort

从零开始打造目前业界性能一流的排序算法 pdasort (Pattern-Defeating-QuickSort

结合三种排序方法的优点:

对于短序列 (小于一定长度) 我们使用插入排序其他情况,使用快速排序来保证整体性能。 当快速排序表现不佳时,使用堆排序来保证最坏情况下时间复杂度仍然O(n*logn) Q&A 1.短序列的具体长度是多少呢 ? ,在不同语言和场景中会有不同,在泛型版本根据测试选定。

2.如何得知快速排序表现不佳,以及何时切换到堆排序? 当最终 pivot 的位置离序列两端很接近时 (距离小于 length/8) 判定其表现不佳,当这种情况的次数达到 limit( 即 bits.Len(lenath)时),切换到堆排序。

pdqsort-version1

image.png 对于短序列 (<=24) 我们使用插入排序其他情况,使用快速排序 (选择首个元素作为 pivot) 来保证整体性能当快速排序表现不佳时 (limit==0) ,使用堆排序来保证最坏情况下时间复杂度仍然为 O(n*logn)。

pdgsort - version2

思考关于 pivot 的选择· 使用首个元素作为 pivot (最简单的方案)实现简单,但是往往效果不好,例如在 sorted 情况下性能很差。 遍历数组,寻找真正的中位数遍历比对代价很高,性能不好。寻找 pivot 所需要的开销。 pivot 带来的性能优化。

根据序列长度的不同,来决定选择策略

Pivot 的采访方式使得我们有探知序列当前状态的能力: 优化-Pivot 的选择短序列(<=8),选择固定元素。 中序列(<=50),采样三个元素, 长序列(>50),采样九个元素。 image.png

还有什么场景我们没有优化?

短序列情况。 使用插入排序(v1)极端情况。 使用堆排序保证算法的可行性(v1) 完全随机的情况 (random·更好的 pivot 选择策略(v2)有序/逆序的情况 (sorted/reverse根据序列状态翻转或者插入排序(v2)。 image.png image.png