算法导论 第8章 线性时间排序
比较排序 指在排序的最终结果各元素的次序依赖于它们之间的比较的排序算法。
在最坏情况下,任何比较排序算法都需要做Ω(nlgn)次比较。因此堆排序和归并排序都是渐近最优的比较排序算法。
本章讨论三种用运算而不是比较来确定排序顺序的线性时间复杂度的排序算法:
- 计数排序
- 基数排序
- 桶排序
计数排序
计数排序 假设n个输入元素中的每一个都是在0~k区间的一个整数,对每一个输入元素x,确定小于x的元素个数,并利用这一信息直接把x放在它输出数组中应该在的位置上:
该过程需要三个数组的空间,输入数组A[1…n],输出数组B[1…n],临时存储空间C[0…k],其中C[i]保存的就是小于或等于i的元素个数。运行过程:
总的运行代价是Θ(k+n),因此在实际应用中当k=O(n)时可以使用计数排序,运行时间为Θ(n)。
计数排序具有一个重要性质即它是稳定的,具有相同值的元素在输出数组中的相对顺序与在输入数组中的相对顺序相同。
基数排序
基数排序 是一种用在卡片排序机上的算法,卡片排序机一次只能查看穿孔卡片的一列,即十进制数字的一位。对于n个d位数,基数排序先按最低有效位进行排序,然后再依次按更高有效位排序,排序方法必须使用稳定的排序方法如计数排序:
运行过程:
给定n个d位数,其中每一位有k个可能取值,则若RADIX-SORT使用的稳定排序方法耗时Θ(n+k),则它可以在Θ(d(n+k))时间内将所有数排序。所以当d为常数且k=O(n)时,基数排序的总时间为Θ(d(n+k))。
桶排序
桶排序 假设输入数据服从均匀分布,其平均时间代价为O(n)。
桶排序将输入区间划分为n个相同大小的子区间,称为桶。然后将输入数分别放在各个桶中,对每个桶中的数进行排序,最后依次序取出各个桶中的元素。具体实现时采用链表来表示桶:
运行过程:
算法中除了第8行的n次插入排序外其他各行时间代价都是O(n),所以桶排序的时间代价为:
两边取期望:
由输入数组A等概率落入任意一个桶,可以推导出:
因此桶排序的期望运行时间:
即使输入数据不服从均匀分布,只要满足所有桶的大小的平方和与总的元素数呈线性关系,则桶排序仍然能在线性时间完成。