数据结构与算法 | 青训营笔记

124 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第11篇笔记.
课前资料: juejin.cn/post/709827…

pqdsort

Version 1

  • 短序列使用插入排序
  • 其他情况下,使用快速排序保证整体性能
  • 快排表现不佳,使用堆排序保证最坏情况下时间复杂度仍为o(nlogn)

Q&A

  • 短序列的具体长度是多少? 12~32.泛型版本根据测试选择24
  • 如何得知快排表现不佳,何时切换到堆排序? 当最终Pivot的位置离序列两段很接近(距离小于length/8),判断其表现不佳。
    当这种情况的次数达到limit(bits.Len(length))时,切换到堆排序。
    那么,如何让pdqsort速度更快
    从快排入手。
  1. 尽量使QSort的pivot为序列中位数->对choose pivot进行改进
  2. Partition速度更快—> 改进Partition,但是此优化效果不好。

Version 2

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

  1. 短序列(<8,固定元素
  2. 中序列(<=50,三数取中
  3. 长序列(>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…