【计数排序】一个效率极高还简单的排序算法

原理

计数排序是一个非基于比较的排序算法,该算法于1954年由Harold H.
Seward提出。它的优势在于在对一定范围内的整数排序时,复杂度为O(n+k)(其中k是整数的范围),快于任何比较排序算法。计数排序的思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。

它的大致流程如下:
一、开辟一个和原数组数值范围一样大的空间,并记录原数组每个值的个数,类似于哈希的映射。
在这里插入图片描述
二、从头到尾遍历辅助空间的下标,如果它的数值不为0就将它次数个下标复制给原数组(因为下标代表原数组的值),又因为它是从头到尾遍历的,所以使用此种方法可以排序。

细节问题

首先这个方法到底要开多少内存呢?如果是按照数组最大值来开辟空间无疑是浪费了大量的空间。

我们知道在使用这个数组的时候,我们只使用了它数组范围内的值来作为下标。

所以我们可以只用他范围内值作为空间,即开辟max - min + 1空间,此时我们再计数的时候就得这么计数tmp[arr[i]-min]++,这么做它最小值对应的下标就是0,其他的数以此类推。

这么优化还有一个优点就是他可以处理负数,例如:

原数组:-4,-9,3,2
最小值:-9
依次对应下标为:(-4-(-9))=5, (-9 - (-9)) = 0, (3-(-9))=12, 11

代码

void CountSort(int* arr, int n)
{
	int mi = INT_MAX, mx = INT_MIN;
	//找最大值和最小值
	for (int i = 0; i < n; i++)
	{
		if(mi > arr[i])
			mi = arr[i];
		if(mx < arr[i])
			mx = arr[i]
	}

	
	int range = mx - mi + 1;
	int* tmp = (int*)calloc(range, sizeof(int));//开辟辅助空间
	
	for (int i = 0; i < n; i++)
	{
		tmp[arr[i] - mi]++;
		//计数
	}
	
	int j = 0;
	//排序的过程
	for (int i = 0; i < range; i++)
	{
		while (tmp[i] > 0)
		{
			arr[j++] = i + mi;
			tmp[i]--;
		}
	}
	
}

总结:

  1. 计数排序是用空间换时间的算法
  2. 时间复杂度o(n), 空间复杂度o(n)
  3. 优点:效率极快
  4. 缺点:虽然可以处理负数,但无法处理小数,字符串,结构体…等多种类型,局限性大

感谢观众老爷的观看Thanks♪(・ω・)ノ,如果觉得满意的话留个关注再走吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值