算法原理:
排序算法根据排序的原理可以分为两类:基于比较的和非比较的。常见的基于比较的排序算法有快速排序,堆排序,归并排序等,基于比较的排序算法平均情况最好是O(nlogn)。基于非比较的排序算法有三种:计数排序,计数排序和桶排序,它们的复杂度为O(n)。
计算排序算法的思想是:对于数组中的 某一个元素x,统计小于x的元素的个数,基于这一信息,在输出的数组上把x放在相应的位置上。
下图是算法导论计数排序部分的示例图。A数组是待排序的输入数组,C是用来存放小于数组中某个元素个数的辅助存储数组。首先对数组中元素的信息进行统计放在C中,然后根据C中的信息得到排序的数组。
算法伪代码:
算法的伪代码出自算法导论中计数排序部分:
COUNTING-SORT(A, B, k)
1. let C[0...k] be a new array2. for i=0 to k3. C[i] = 04. for j=1 to A.length5. C[A[j]] = C[A[j]] + 16.//C[i] now contains the number of elements equals to i7. for i=1 to k8. C[i] = C[i] + C[i-1]9.//C[i] now contains the number of elements less than or equal to i10.for j=A.length downto 111. B[C[A[j]]] = A[j]12. C[A[j]] = C[A[j]] - 1
算法性能分析:
时间复杂度分析:根据伪代码很容易看出计算排序的时间复杂度是O(n)。
空间复杂度分析:O(n)
稳定性:稳定
适用场景:1. 待排序的数组为非负整数
2. 知道待排序数组的取值范围3. 数组中的最大数比总数小(数据范围大的数组会消耗大量的时间和内存)4. 基数排序中对每一位的排序使用计数排序
Java版本代码实现:
private void sort(int[] A, int[] B, int k)
{
int[] C = new int[k];
for(int i=0;i<A.length;i++)
C[A[i]]++;
for(int i=1;i<k;i++)
C[i] += C[i-1];
for(int i=A.length-1;i>=0;i--)
{
B[C[A[i]]-1] = A[i];
C[A[i]]--;
}
}