对于排序,我们熟知的合并排序,快速排序,堆排序,插入排序,冒泡排序,选择排序都是属于比较类的排序,这种排序有一个时间复杂度的下限,即排序所需要的最低时间复杂度是O(nlongn);然而还有一些排序在特定情况下时间复杂度能达到O(n),即线性时间复杂度,今天在这里写一下时间复杂度为O(n)的—————-计数排序。
计数排序算法:
1.输入一个整数数组A,我们需要为一个B数组用来存储排序好的值,一个C数组用来计数C[i]=0,C数组的长度是A数组中数值的范围,我们从A数组首元素出发,对于A[i]中的值,以A[i]为C数组的下标,计算C[A[i]]++。
2.这只是初始的C[i],我们需要进一步计算C[i]=C[i]+C[i-1];
3.接下来,我们将要联系A,C数组,将排好的值赋给B。我们从B数组的最后一个下标开始往前进行循环B[C[A[i]]]=A[i];C[A[i]]–;
结论:计数排序在K值较小时K=A数组值范围,有较低的时间复杂度,但是K值过大需要的辅助数组将会非常大,效率将会大大降低,不是很好的算法。
JAVA实现:
public class CountSortEX1 {
public void countingSort(int[] a){
int[] b=new int[a.length];
int max=a[0],min=a[0],k;
for(int i=1;i<a.length;i++){
if(a[i]>max){
max=a[i];
}
if(a[i]<min){
min=a[i];
}
}
k=max-min+2;
int[] c=new int[k];
for(int i=0;i<k;i++)
c[i]=0;
for(int i=0;i<a.length;i++){
c[a[i]]++;
}
for(int i=1;i<c.length;i++){
c[i]=c[i]+c[i-1];
}
for(int i=b.length-1;i>=0;i–){
b[c[a[i]]-1]=a[i];
c[a[i]]–;
}
for(int i=0;i<a.length;i++)
a[i]=b[i];
}
public static void main(String[] args){
CountSortEX1 cse=new CountSortEX1();
int[] a={9,5,7,3,2,1,6,1,9,11,15,12,17,13,19,11,21,10,20,14};
cse.countingSort(a);
for(int b:a)
System.out.print(b+” “);
System.out.println();
}
}