go语言排序| 青训营笔记

75 阅读2分钟

经典排序

插入排序、快速排序、堆排序

  • 插入排序
    • 将元素不断插入已经排序好的array中,后续元素插入有序序列中 ,直到找到第一个比其小的元素
  • 快速排序
    • 分治思想,用一个pivot(轴点)不断分割序列使序列一边大,一边小直到有序
  • 堆排序
    • 利用堆的性质,构造大顶堆,将根节点(最大元素)交换到最后一个位置,调整整个堆,如此反复 根据序列长(1024)中(128)短(16),插入排序短序列最快(适合短序列和有序序列性能最好),快速排序中长最快(大部分情况下综合性能好),堆排序稍慢于最快速度算法(任何情况下都很稳定)

pdqsort

go1.19中一种不稳定的混合排序算法,对常见的序列类型做了特殊的优化,各种条件下都拥有不错的性能.(结合了上述三种排序方法的优点,短序列(12-32)插入,其他情况快排,快排表现不佳时用堆排序兜底)

如何让pdqsort更快

尽量使得QuickSort的pivot为序列的中位数(改进chooseee pivot),但是实现真正的中位数需要遍历,带来一些性能的开销,所以只要找到近似的中位数就可以。

根据长度的不同决定选择近似中位数策略

  • 短序列(<=8),固定元素
  • 中序列(<=50),采样三个元素
  • 长序列(>50),采样九个元素
  1. 如果在有序或逆序的情况下可以根据序列状态翻转或者插入排序,进行性能优化
  2. 如果在重复元素过多的情况下检测到两次的pivot选择相同,使用partitionnEqual将重复元素排列在一起,来优化性能