排序 计数排序

来源:互联网 发布:淘宝售后客服绩效考核 编辑:程序博客网 时间:2024/06/06 01:48
计数排序主要思想:
  给定一组要排序的序列,找出这组序列中的最大值,然后开辟一个最大值加1大小的数组,将这个数组里面的元素全部置零,然后用这个数组统计出要排序的序列中各个元素出现的次数。等到统计完成的时候,排序就已经完成了。
例:


  计数排序是一种非比较的排序方法,它的时间复杂度是O(N+K),空间复杂度是0(K),其中K是要排序的数组的范围。可以看出计数排序是一种以空间呢换取时间的方法。如果当K>N*logN的时候,计数排序就不是好的选择了,因为基于比较排序的算法的下限是O(N*logN)。

优化:
  可以看出,计数排序使用于待排序的元素值比较集中的情况。假如先在对1001,1005,1008这三数进行排序,按照上面的方法前1000个空间都被浪费掉了,所以这时候我们对它进行优化。
  我们可以找出要排序的这组元素中的最大值和最小值,这样就确定了这组元素的范围,然后开辟这个范围加1大小的数组,然后再将要排序的元素映射到这个新开辟的数组中就可以了。


实现:
[cpp] view plain copy
  1. void CountSort(int *a,int n)  
  2. {  
  3.        assert(a);  
  4.        int max = a[0];  
  5.        int min = a[0];  
  6.        //先找到这组数据中的最大值和最小值  
  7.        for (int i=1; i < n; ++i)  
  8.        {  
  9.               if (a[i]>max)  
  10.                      max = a[i];  
  11.               if (a[i]<min)  
  12.                      min = a[i];  
  13.        }  
  14.        int range = max - min + 1;  
  15.        int *tmp =new int[range];           //辅助数组,用来统计每个数出现的次数  
  16.        memset(tmp,0,sizeof(int)*range);  
  17.        for (int i = 0; i <n;i++)           //统计数组a中每个数出现的次数  
  18.        {  
  19.               tmp[a[i]-min]++;  
  20.        }  
  21.        int index = 0;  
  22.        for (int i = 0; i < range; ++i)      //将排好的数拷贝回a中  
  23.        {  
  24.               while (tmp[i]--)  
  25.                      a[index++] =i+min;  
  26.        }  
  27.        delete[] tmp;  
  28. }