这是我参加第五期青训营 x 字节后端训练营的第一篇笔记,字节青训营给了初学者一个很好的学习平台和和了解企业需求的窗口,给作为大一的萌新的我一个很大的震撼。
本文是对后端入门 - Go 1.19 排序算法实践的笔记,按照老师的分块进行大纲笔记
01 为什么要学习数据结构与算法
数据结构与算法几乎被用在了所有程序开发的过程中,合理的排序算法能大大减少程序运行的时间、增加效率。
在一些情景下优化过的排序算法,有时会比Go 语言的默认算法要更快。
02 经典排序算法
插入排序
故名思意,插入排序通过不断将新的元素插入到已排好的序列当中,来实现所有元素的排序。
时间复杂度在 n - n^2 中间,平均下来为 n^2 的复杂度,需要 n 个数据的空间。
快速排序
通过不断分割排序为 (<pirvot)(>=pirvot) 两个部分来实现元素的排序。
时间复杂度在 n - n^2 中间,平均下来为 n logn 的复杂度,需要 n 个数据的空间。
堆排序
利用 heap 来实现的算法,通过不断在插入输出后调整数据,来实现排序。
一般根节点为具有某种性质(例如大小是最大、最小)的元素。
时间复杂度为n logn ,平均下来为 n logn 的复杂度,需要 n 个数据的空间,最差的情况比其他排序的要好,而最好的情况不如其他排序。
选择
根据序列的大小来选择排序:
- 插入排序在短序列中速度最快
- 快速排序在其他情况中速度最快
- 堆排序速度于最快算法差距不大
- 插入排序在序列已经有序的情况下最快
03 从零开始打造 pdqsort
如何设计一个更好的算法呢?
qpqsort 是一种混合排序算法,它对常见的序列都进行了一些优化,使得它能有不错的性能
qpqsort - vesion 1 如下:
- 对于短序列(小于一定长度)我们使用插入排序
- 其他情况,使用快速排序来保证整体性能
- 当快速排序表现不佳时,使用堆排序来保证最坏情况下时间复杂度仍然为 O(n*logn)
其他还可以进行的优化有很多,例如:
-
更好地去选择 privot
-
根据样例推断状态,进行翻转等操作