introduction to algorithms sorting lesson_6 Counting sort (计数排序)

来源:互联网 发布:淘宝店铺介绍是什么 编辑:程序博客网 时间:2024/06/05 22:59

   计数排序 可在线性时间 即O(n)时间内完成排序。而前几节中的排序,如插入排序、归并排序、快速排序、堆排序、希尔排序这几种

都属于比较排序,即是排序中均通过比较的方法,且可以证明无论何种比较排序,总的比较次数下确界为 O(nlogn),性能无法再提高

    计数排序是线性时间内完成的排序,其基本思想:

    不通过元素的比较,而是通过统计比元素data[i]或者大的元素有多少个,知道这个信息等于知道data[ i ]插入的位置

而统计的基本方法 就是计数。


  假设知道待排序的数组 中数值的最大值,即假定data[] 数据,最大值为K,分布为0  ~  k

  所以需要一个临时的计数数组cnt[]来统计 data[]中没一个数值有多少个 则length( cnt[] )=k+1;

 还需要一个与 data 同样长度的数组 newdata[]来将data[ ]中的元素,根据cnt[ ]的信息插入到 newdata中去

  这就是计数排序的基本思想及步骤。

 下面用代码实现:

     为了使思路更清晰,代码比较多,可以优化:对于纯粹数组,则newdata可以省略实现原地排序,因为cnt的下标即为data元素数值,对于其他结构则不可以

/***********  counting sort***************/void CountingSort(int data[],int len,int k)    //the value of data  distribute from  0  to k   k is  the max value{  int *cnt=(int*)malloc((k+1)*sizeof(int));//get array memory  int *newdata=(int*)malloc(len*sizeof(int));   //new data  int i;  for (i=0;i<=k;i++)                          //assign cnt array    cnt[i]=0;  for (i=0;i<len;i++)                    //包含等于i的元素个数cnt[data[i]]++;          for (i=1;i<=k;i++)                   //包含小于等于i的元素个数   cnt[i]+= cnt[i-1];  for (i=len-1;i>=0;i--)         //根据cnt array直接赋值给newdata,即可完成排序  {   newdata[cnt[data[i]]-1]=data[i]; //-1是因为数组下标从0开始  cnt[data[i]]--;  }    for (i=0;i<len;i++)           //重新赋值给原数组     data[i]=newdata[i];  free(cnt);  free(newdata);}


算法分析:主要分为两部分,以上cnt的赋值操作 运行时间为O(K),后面是data的计数操作,运行时间为O(N),

故总的运行时间为O(k+n)

虽然计数排序能在线性时间内完成排序,效率极高,但必须知道待排序数据的范围,以及待排序数据分布不可以太零散,需比较集中


0 0
原创粉丝点击