计数排序主要思想:
给定一组要排序的序列,找出这组序列中的最大值,然后开辟一个最大值加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;
}


1038

被折叠的 条评论
为什么被折叠?



