数据结构与算法的个人总结 | 青训营笔记

259 阅读1分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记,此次主要讲解Golang中<=1.18的默认排序算法,以及新版本中优化过后的sort算法,老师先是从最基础的插入排序、快速排序和堆排序开始讲解,介绍了各个算法的优势与不足之处,最后引出本次课程的重头戏pdqsort及其优化过程。下面是详细笔记:

数据结构与算法

主流语言的默认排序算法

python Timsort

c++ introsort

rust pdqsort

Go ≤1.18 是introsort

经典排序算法

插入排序

时间复杂度

最好O( n )

平均O(n ^ 2)

最坏O(n ^ 2)

快速排序 分治的思想,选取一个pivot

最好O( nlogn )

平均O( nlogn )

最坏O(n ^ 2)

堆排序 利用堆的性质构造一个大根堆(或者是小根堆),然后将根节点交换到最后一个位置,再重新调整堆,直至排序完成。

最好O( nlogn )

平均O( nlogn )

最坏O( nlogn )

有一个benchmark 的实验

直接上结论

  1. 插入排序在短序列中速度最快
  2. 快速排序在其他情况中速度最快
  3. 堆排序速度于最快算法差距不大

引入pdqsort算法

pdqsort pattern-defeating-quicksort 是一种不稳定的混合排序算法。

v1

对于短序列来说使用插入排序

其他情况使用快速排序来保证整体性能

这个需要考虑快速排序性能不佳的时候,选用堆排序来改善算法性能

截屏2022-05-20 17.50.38.png

这里的limit是用来判读快速排序表现不佳时的依据。

v2

在快速排序中选取pivot对于性能的影响还是很大的

所以通过优化pivot的选取来实现pdqsort性能的提升

当然寻找pivot的开销需要和带来的性能进行平衡, 需要寻找一个近似的中位数

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

短序列 ≤8 选择固定的三个数

中序列 ≤50 采样三个元素

长序列 >50 采样九个元素

截屏2022-05-20 17.49.59.png

升级了选择pivot的策略

发现序列逆序的话则反转序列

发现有序则使用插入排序

最终的pdqsort go1.19默认排序

截屏2022-05-20 17.49.08.png