这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
前言
排序算法基本上算是我接触数据结构与算法的一块敲门砖了,这次接触到pdqsort,对比下之前学习的排序算法进行学习,还记得当时刚开始接触到的排序是冒泡排序,到后来随着知识体系的逐步完善,慢慢的也就在刷题过程中直接调algorithm库的sort()函数进行排序了,在这里也给大家分享下我当初的一个比较平缓的排序学习路线,希望对刚接触排序算法的小伙伴有一定的帮助
graph LR
冒泡排序 --> 选择排序 --> 插入排序--> 希尔排序--> 堆排序--> 桶排序--> 快速排序--> 归并排序
一、pdqsort简介
pdqsort是一种不稳定的混合排序算法,他的不同版本被应用到C++,BOOST,Rust以及Go1.19中。他对常见的序列类型做了特殊的优化,使得他在不同条件下都拥有不错的性能
二、pdqsort版本迭代
version 1:
- 对于短序列(<=24)使用插入排序
- 其他情况,使用快速排序(选择首个元素作为pivot)来保证总体性能
- 当快速排序表现不佳时(limit==0),使用堆排序来保证最坏情况下时间复杂度仍为O(n*logn)
思考:如何让version1更快?
- 尽量使得QuickSort的pivot为序列的中位数->改进choose pivot
- Patition速度更快->改进patition,但是此优化在go表现不好,略
version 2:
- 升级pivot选择策略(近似中位数)
- 发现序列可能逆序,则翻转序列->应对reverse场景
- 发现序列可能有序,使用有限插入排序->应对sorted场景
思考:还有什么场景没有优化?
- 短序列情况
- 极端情况
- 完全随机情况(random)
- 有序/逆序情况(sorted/reverse)
- 元素重复度高的情况(mod8)
version final:
三、pdqsort复杂度对比与性能分析
一台云服务器上测试
- 在有序情况或者逆序情况提升10x
- 其他情况下有10-50%的提升