一、计数排序的原理:
1.计数排序是一种以空间换时间的线性时间的排序方法,有三个数组完成,其中A数组代表了待排序的数据,B数组用来存放排好序后的数据,C数组是扩展数组,用来存放小于等于各个元素的个数。对于任一元素,当我们知道了小于等于此元素的元素个数的时候,我们便能确定此元素的位置。
2.计数排序采用倒序来完成元素的排序存放,是因为这样可以保持在待排序数组中重复元素的相对位置,保证算法是稳定的。
3.由于计数排序的扩展的数据空间的大小依赖待排数据的取值范围,所以,对于待排数据范围较大的情况是不适用的。
4.计数排序对于小型的且数据范围不是很大的数据进行排序的时间复杂度很小,效率很快
二、计数排序的实现步骤:
1.确定待排数据的范围
2.确定扩展数组的大小,为数据最大范围+1
3.求出每个元素的出现个数
4.计算小于等于每个元素的元素个数
5.对待排元素倒序进行排序
三、算法实现:
void count_sort(int *a,int *b,int n)
{
int c[K]={0}; //临时数组
int i =0;
for(i=0;i<n;i++)
c[a[i]]++;//c[i]包含等于i的元素个数,生成计数的数组
for(i=1;i<K;i++)
c[i]+=c[i-1];//此时,c[i]包含小于等于i的元素个数
//进行排序,b数组是最终排好序的数组
int j = 0;
for(j= n-1;j>=0;j--)
{
b[c[a[j]]-1] = a[j];
c[a[j]]--;//为了相同的元素
}
}
以下转载:http://blog.youkuaiyun.com/neilhappy/article/details/7202507
计数排序的扩展
1.对负数排序的扩展思路:计数排序要求元素能够作为数组的下标,自然不能是负数。我的思路是先把负数和非负数分离开来,对负数取绝对值,再对这两组数分别计数排序,最后再把两组数合并可以了。时间复杂度依旧是O(n),只是n会大一点。当然处理的都是整数。
2.对浮点数排序的扩展思路:浮点数不能作为数组下标。先后否定了自己两个比较鸡肋的办法,这里写一个我认为可以作为基础的算法,但是还需要非常大的改进。把一个浮点数存储在一个链表中,每个结点存储一位,然后对每一组结点进行计数排序。这样会导致O(n2)的时间复杂度,我还没想到如何进行优化,如果您有思路,请告诉小弟我,非常感谢。
总结:计数排序不是就地排序,需要借助一个辅助空间并且存储结果到另一个空间,而且适用范围相对狭窄,但是却有着O(n)的时间复杂度。我现在理解到算法设计就是在时间和空间,以及适用范围之间找一个最优的平衡点。