首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【计数排序】一个效率极高还简单的排序算法

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

作者头像
用户11935701
发布2025-12-16 08:40:38
发布2025-12-16 08:40:38
1710
举报

原理

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

它的大致流程如下: 一、开辟一个和原数组数值范围一样大的空间,并记录原数组每个值的个数,类似于哈希的映射。

二、从头到尾遍历辅助空间的下标,如果它的数值不为0就将它次数个下标复制给原数组(因为下标代表原数组的值),又因为它是从头到尾遍历的,所以使用此种方法可以排序。

细节问题

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

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

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

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

代码语言:javascript
复制
原数组:-4,-9,3,2
最小值:-9
依次对应下标为:(-4-(-9))=5, (-9 - (-9)) = 0, (3-(-9))=12, 11

代码

代码语言:javascript
复制
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♪(・ω・)ノ,如果觉得满意的话留个关注再走吧。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理
  • 细节问题
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档