排序(10)——非比较排序计数排序

目录

思想

局限性 

基本思路

代码实现

 特性总结


思想

思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:

  1. 统计相同元素出现次数
  2. 根据统计的结果将序列回收到原来的序列中

首先有一个a数组,里面都有元素,然后再创建一个count数组,把a数组里的数字当作count的下标,比如上面A数组里第一元素是2,那么我们就让count数组下标为2的位置+1,依次往后。最后把count里的数按元素个数依次打印出来,就有序了。 

局限性 

  1. 不适合分散的数据,更适合集中数据
  2. 不适合浮点数、字符串、结构体数据排序,只适合整数 

基本思路

绝对映射:a中的数是几,count中的下标就是几。

  • 但这样可能会导致很大一部分空间就浪费了

相对映射: a中的数是x,count中的下标就是x-min。所以count中,最小下标为0,最大下标为max-min

  • count[ a[i]-min ]++;
  1. 首先先遍历a数组,找min和max
  2. 然后创建新数组count,数组中的元素需要全部初始化为0 (calloc)         
  3. 再遍历原数组统计次数
  4. 最后一一映射回去,注意最开始我们-min,把这个数当作count的下标。那么映射回去的时候,每一个下标都要+min后再返回给原数组。
  • range=max-min+1 即count中的元素个数
  • while(count[j]--),j是几就循环几次。
  • 注意--前后置的区别。

代码实现

void CountSort(int* a, int n)
{
	int min = a[0], max = a[0];
	for (int k = 1; k < n; k++)
	{
		if (a[k] < min)
			min = a[k];

		if (a[k] > max)
			max = a[k];
	}

	int range = max - min + 1;
	int* count = (int*)calloc(range, sizeof(int));
	if (count == NULL)
	{
		printf("calloc fail\n");
		return;
	}

	// 统计次数
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}

	// 排序
	int i = 0;
	for (int j = 0; j < range; j++)
	{
		while (count[j]--)
		{
			a[i++] = j + min;
		}
	}
}

奇妙的是,负数也可以排序。原因是我们前面在找min时,min就是负数,后面我们在统计次数化空间的时候,a[i]-min也是将最小负数放在了count数组中下标为0的位置,并不存在越界什么的。  相对映射可以解决!

 特性总结

1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
2. 时间复杂度:O(MAX(N,范围))
3. 空间复杂度:O(范围)

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值