这是我参与「第三届青训营 -后端场」笔记创作活动的的第11篇笔记.
课前资料: juejin.cn/post/709827…
pqdsort
Version 1
- 短序列使用插入排序
- 其他情况下,使用快速排序保证整体性能
- 快排表现不佳,使用堆排序保证最坏情况下时间复杂度仍为o(nlogn)
Q&A
- 短序列的具体长度是多少? 12~32.泛型版本根据测试选择24
- 如何得知快排表现不佳,何时切换到堆排序?
当最终Pivot的位置离序列两段很接近(距离小于length/8),判断其表现不佳。
当这种情况的次数达到limit(bits.Len(length))时,切换到堆排序。
那么,如何让pdqsort速度更快?
从快排入手。
- 尽量使QSort的pivot为序列中位数->对choose pivot进行改进
Partition速度更快—> 改进Partition,但是此优化效果不好。
Version 2
根据序列长度不同,来决定选择策略
优化pivot的选择:
- 短序列(<8,固定元素
- 中序列(<=50,三数取中
- 长序列(>50,采用九个元素,九数的各三数取中的三数取中
那么,如何让pdqsort速度更快?
- 短序列->强制插入排序
- 极端情况->使用堆排序
- 完全随机时->快排中更好的选择pivot
- 有序/逆序-》翻转/插入排序
- 重复元素很多时?
Final Version
如何优化重复元素很多的情况?
不建议使用采样处理,因为采样数量有限,不一定能采样到重复元素。
解决方案: 如果两次partition生成的pivot相同,即Partition进行了无效分割,此时认为pivot是重复元素
当检测到此时的pivot与上次相同,将重复元素排列在一起,减少重复元素对pivot选择的干扰。
公众号:mp.weixin.qq.com/s/5HqfRGqPy…
源码:github.com/golang/go/b…
issue:github.com/golang/go/i…
论文:arxiv.org/pdf/2106.05…
大佬的github:github.com/zhangyunhao…