pdq排序算法分析|青训营笔记

1,374 阅读1分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记

前言

排序算法基本上算是我接触数据结构与算法的一块敲门砖了,这次接触到pdqsort,对比下之前学习的排序算法进行学习,还记得当时刚开始接触到的排序是冒泡排序,到后来随着知识体系的逐步完善,慢慢的也就在刷题过程中直接调algorithm库的sort()函数进行排序了,在这里也给大家分享下我当初的一个比较平缓的排序学习路线,希望对刚接触排序算法的小伙伴有一定的帮助

graph LR
冒泡排序 --> 选择排序  --> 插入排序--> 希尔排序--> 堆排序--> 桶排序--> 快速排序--> 归并排序

一、pdqsort简介

pdqsort是一种不稳定的混合排序算法,他的不同版本被应用到C++,BOOST,Rust以及Go1.19中。他对常见的序列类型做了特殊的优化,使得他在不同条件下都拥有不错的性能

二、pdqsort版本迭代

version 1:

image.png

  • 对于短序列(<=24)使用插入排序
  • 其他情况,使用快速排序(选择首个元素作为pivot)来保证总体性能
  • 当快速排序表现不佳时(limit==0),使用堆排序来保证最坏情况下时间复杂度仍为O(n*logn)

思考:如何让version1更快?

  • 尽量使得QuickSort的pivot为序列的中位数->改进choose pivot
  • Patition速度更快->改进patition,但是此优化在go表现不好,略

version 2:

image.png

  • 升级pivot选择策略(近似中位数)
  • 发现序列可能逆序,则翻转序列->应对reverse场景
  • 发现序列可能有序,使用有限插入排序->应对sorted场景

思考:还有什么场景没有优化?

  • 短序列情况
  • 极端情况
  • 完全随机情况(random)
  • 有序/逆序情况(sorted/reverse)
  • 元素重复度高的情况(mod8)

version final:

image.png

三、pdqsort复杂度对比与性能分析

image.png

一台云服务器上测试

  • 在有序情况或者逆序情况提升10x
  • 其他情况下有10-50%的提升

image.png