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

133 阅读2分钟

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

数据结构与算法不仅仅局限于课本中,真正的实际生产实践中,数据结构与算法也有着很大的作用。

青训营的算法教学主要是介绍了最常用的算法--排序算法。Go语言在1.18及以前版本使用的是introsort排序算法,而go1.19将采用更优的排序算法--pdqsort,使得排序总体效率高于原先算法,同时在某些常见场景更是可以大幅度提升。

pdqsort(pattern-defeating-quicksort)主要是结合了三种非常常见的排序算法,插入排序,快速排序和堆排序。插入排序是课堂常见的算法,不再赘述。堆排序之前了解得不多,也在之前自己学习了一下并写在了第2篇笔记。

pdqsort使用的三种算法各有其优缺点

三种排序算法的优缺点
排序算法优点缺点
插入排序实现简单,无需处理即可使用,短序列效率高复杂度为n^2,序列长时耗时极长
快速排序平均性能好,可以处理大多数情况遇到极端情况会退化成O(n^2),耗时大幅增加
堆排序稳定的O(nlogn)算法,可以处理极端情况过于稳定,对于特殊情况无法加快排序

显然,三种排序算法各有其优缺点,而将三者合成一种算法,就能取长补短,成为真正的高效排序算法。

使用不同排序算法的情况

1.对于短序列的情况使用插入排序,具体长度为12-32。一般可以选择24,即:长度小于等于24的序列进行排序时,使用排序算法。

2.否则使用快速排序。而使用快速排序最重要的地方就是适时发现当前序列使用快排效率不高,进而转化到堆排序,以此保证整体复杂度仍然为O(nlogn).

3.当最终pivot(支点)的位置离序列两端接近时(距离小于length/8)达到一定次数(limit=bits.Len(length))时,可以判断快排很多次都都进行了效率低下的排序,进而可以判断该序列大概率属于极端序列。因此切换为堆排序。

4.而堆排序作为一种稳定的排序,没有什么特殊情况,正常使用就行。

其他--快速排序的一个优化

快速排序中的pivot选择:采样,短序列(length<=8)时,采用固定元素。中序列(<=50)采样三个点。长序列采样九个点。选择采样点中合适的点来作为pivot。