计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。
计数排序的基本思想就是对于每一个输入元素x,确定出小于x的元素个数。有了这一信息就可以把x直接放到它在最终输出数组中的位置上。
例如,如果有17个元素小于x,则x就属于输出数组中的第18个位置。
在计数排序算法的代码中,我们假定对含有n个元素的数组A[0..n-1]进行排序,排序结果存放在数组B[0..n-1]中,保证A中的所有元素都不超过k。
建立一个临时数组C[0..k]储存临时数据。
void CountingSort(int A[],int B[],int n,int k){
for (int i=0;i<=k;i++) C[i]=0;
for (int i=0;i<n;i++) C[A[i]]++;
/// C[i] 包含等于 i 的元素个数
for (int i=1;i<=k;i++) C[i]+=C[i-1];
/// C[i] 包含小于或等于 i 的元素个数
for (int i=n-1;i>=0;i--)
{
C[A[i]]--;
B[C[A[i]]]=A[i];
}
}
计数排序的时间代价是多少?
第一个循环:O(k)
第二个循环:O(n)
第三个循环:O(k)
第四个循环:O(n)
总的时间就是O(n+k)
计数排序的一个重要性质就是它是稳定的:具有相同值的元素在输出数组中的相对次序与它们在输入数组中的次序相同。
亦即,两个相同数之间的顺序是这样来规定的,即在输入数组中先出现的,在输出数组中也位于前面。
之所以说计数排序的稳定性非常重要,有一个原因,即计数排序可以作为基数排序的一个子过程。
基数排序可以对有多个关键字的元素进行排序。
基数排序首先对所有元素按最低有效位进行排序,然后按次低有效位排序,直到把所有关键字都进行了排序。
关于这个算法,很重要的一点就是按位排序要稳定。
假设我们想根据三个关键字年月日来对日期进行排序。
我们可以用计数排序先以日排序,其次对月排序,最后对年排序。
这样进行三遍计数排序后,日期就排好序了。