排序算法|青训营笔记

97 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第17天。

详解经典排序算法

展示排行榜的解决方法

1.礼物数量存储在Redis-zset中,使用skiplist使得元素整体有序。

2.使用Redis集群,避免单机压力过大,使用主从算法、分片算法。

3.保障集群原信息的稳定,使用一致性算法。

4.后端使用缓存算法降低Redis压力,展示房间排行榜。

最快的排序算法:introsort(C++、Go(1.18及之前版本))、timesort(Python)、pdqsort(Rust、GO(1.19及之后版本))。

插入排序:将元素不断插入已经排好的array中。

插入排序时间复杂度:平均O(n^2),最好O(n),最差(n^2)。

插入排序缺点:平均和最差时间复杂度太高。

快速排序:分治思想,不断分割序列直到整体有序。

快速排序时间复杂度:平均O(nlogn),最好O(nlogn),最差(n^2)。

插入排序缺点:最差时间复杂度太高。

Heap Sort堆排序:利用堆的性质排序。

Heap Sort堆排序时间复杂度:平均O(nlogn),最好O(nlogn),最差(n*logn)。

Heap Sort堆排序缺点:最好时间复杂度太高。

归并排序:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

基数排序:基数排序(Radix Sort)是桶排序的扩展,它的基本思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较。将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

从零开始打造 pdqsort

pdqsort:是一种不稳定的混合排序算法。

pdq的结合思路:一般用快速排序,对于小于一定长度的序列使用插入排序,快速排序表现不佳时使用快速排序。

短序列的具体长度:12~32,在官方使用的函数中选定的是24。

得知快速排序表现不佳的方法:当最终的pivot离序列两端的距离小于序列长度的八分之一,记为一次,当次数达到bits.Len(length)时,则判定快速排序表现不佳表现不佳。

优化的思路:改进choose pivot,改进partition。

优化choose pivot:当序列长度小于等于8时,选择第一个元素为pivot,当序列长度大于8小于等于50,选择第一个元素、中间位置的元素、最后一个元素三个元素的中位数为pivot,当序列长度大于50时,采样9个元素的中位数为pivot。

对于重复元素较多情况的优化:当此次的pivot和上次的pivot一样,将重复元素排列在一起。

pdq排序流程