计数排序

计数排序主要思想:
  给定一组要排序的序列,找出这组序列中的最大值,然后开辟一个最大值加1大小的数组,将这个数组里面的元素全部置零,然后用这个数组统计出要排序的序列中各个元素出现的次数。等到统计完成的时候,排序就已经完成了。
例:


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

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


实现:
void CountSort(int *a,int n)
{
       assert(a);
       int max = a[0];
       int min = a[0];
       //先找到这组数据中的最大值和最小值
       for (int i=1; i < n; ++i)
       {
              if (a[i]>max)
                     max = a[i];
              if (a[i]<min)
                     min = a[i];
       }
       int range = max - min + 1;
       int *tmp =new int[range];           //辅助数组,用来统计每个数出现的次数
       memset(tmp,0,sizeof(int)*range);
       for (int i = 0; i <n;i++)           //统计数组a中每个数出现的次数
       {
              tmp[a[i]-min]++;
       }
       int index = 0;
       for (int i = 0; i < range; ++i)      //将排好的数拷贝回a中
       {
              while (tmp[i]--)
                     a[index++] =i+min;
       }
       delete[] tmp;
}
































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值