第8章 线性时间排序
8.1 排序算法的下界
定理:在最坏情况下,任何比较算法都需要做Ω(nlgn)次比较。
证明:通过一个决策树模型来分析,对于一颗每个排列都是一个可达的叶节点的决策树来说,树的高度可以被确定。考虑一颗高度为h,具有
n!≤l≤2h
对该式两边取对数,有
h≥lg(n!)=Ω(nlgn)
堆排序和归并排序都是渐进最优的比较排序算法。
8.2 计数排序
int[] countSort(int A[], int B[], int k, int length){
int C[] = new int[k + 1];
for(int i = 0;i < length;i++)
C[A[i]] += 1;
for(int i = 1;i <= k;i++)
C[i] += C[i - 1];
for(int i = length - 1;i >= 0;i--){
B[C[A[i]]] = A[i];
C[A[i]] -= 1;
}
return B;
}
总的时间代价是Θ(k+n),当k=O(n)时,我们一般会采用计数排序,这时的运行时间为Θ(n)
8.3 基数排序
REDIX-SORT(A, d)
for i =i to d
use a stable sort to sort A on digit i
引力:给定n个d位数,其中每一个数位有k个可能的取值。如果RADIX-SORT使用的稳定排序方法耗时Θ(n+k),那么它就可以在Θ(d(n+k))时间内将这些数排好序。
8.4 桶排序
BUCKET-SORT(A)
n = A.length
let B[0..n-1] be a new array
for i = 0 to n-1
make B[i] an empty list
for i = 1 to n
insert A[i] into list B[nA[i]]
for i = 0 to n-1
sort list B[i] with insertion sort
concatnate the lists B[0],B[1],...,B[n-1] together in order
假设ni是表示桶B[i]中元素个数的随机变量,因为插入排序的时间代价是平方阶的,所以桶排序的时间代价为:
T(n)=Θ(n)+∑i=0n−1O(n2i)
桶排序的期望运行时间为
Θ(n)+n⋅O(2−1/n)=Θ(n)