目录
11 | 排序(上):为什么插入排序比冒泡排序更受欢迎?
冒泡、插入、选择 O(n^2)
快速、归并 O(nlogn)
计数、基数、桶 O(n)
排序算法的执行效率
最好情况、最坏情况、平均情况时间复杂度
时间复杂度的系数、常数、低阶
比较次数和交换(或移动)次数
排序算法的内存消耗
排序算法的稳定性,对于对象的排序
冒泡排序(Bubble Sort)
逆序度
插入排序(Insertion Sort)
冒泡排序、插入排序交换(或移动)次数 = 逆序度
从代码实现上看,冒泡排序的数据交换要比插入排序的数据移动要复杂,冒泡排序需要3个赋值操作,而插入排序只需要1个,所以在对相同数组进行排序时,冒泡排序的运行时间理论上要长于插入排序
选择排序(Selection Sort),不稳定
12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?
归并排序(Merge Sort)
归并排序不是原地排序算法
快速排序(Quick Sort)
13 | 线性排序:如何根据年龄给100万用户数据排序?
线性排序:桶排序、计数排序、基数排序
适用场景
桶排序比较适合用在外部排序中。所谓的外部排序就是数据存储在外部磁盘中,数据量比较大,内存有限,无法将数据全部加载到内存中。比如说我们有 10GB 的订单数据,我们希望按订单金额(假设金额都是正整数)进行排序,但是我们的内存有限,只有几百 MB,没办法一次性把 10GB 的数据都加载到内存中。
计数排序是桶排序的一种特殊情况,只能用在数据范围不大的场景中
计数之后,如何对原始数组排序?形成累计计数数组,从后向前遍历原数组,放入相应位置,并更新累计计数数组。
基数排序对要排序的数据是有要求的,需要可以分割出独立的“位”来比较,而且位之间有递进的关系,如果 a 数据的高位比 b 数据大,那剩下的低位就不用比较了。除此之外,每一位的数据范围不能太大,要可以用线性排序算法来排序,否则,基数排序的时间复杂度就无法做到 O(n) 了。
14 | 排序优化:如何实现一个通用的、高性能的排序函数?
快排中分区点的选择:三数取中法、随机法
glibc中的qsort()函数
把思考的过程看得比标准答案更重要