排序算法 - 计数排序

计数排序(Count sort)

用待排序序列的记录作为计数数组的下标,统计每个记录的个数,然后依次输出计数数组的下标,

即可得到有序序列。

基本思路

  1. 初始化一个计数数组,数组大小为所有记录中最大的数
  2. 遍历待排序序列,按照一定规则将记录映射到计数数组的下标
  3. 存在对应记录则该位置下标+1
  4. 把计数数组直接覆盖到输出数组(节约空间)

代码实现

void CountSort(int a[],int n) {//待排序数组a,长度n
	int tmp[10000];//临时辅助数组,根据待排序数组的最大元素设置大小
	memset(tmp,0,sizeof(tmp));//初始化为0
	for(int i=0; i<n; i++)
		tmp[a[i]]++;
	int index=0;
	for(int i=0; i<10000; i++)//覆盖回原数组
		if(tmp[i]!=0)
			while(tmp[i]--)
				a[index++]=i;
}

复杂度

时间复杂度:O(n + k),n是输入数组长度,k是最大的数的大小

空间复杂度:O(n + k),n是输入数组长度,k是最大的数的大小

特点

  1. 非比较的、稳定的、排序算法
  2. 快,线性时间复杂度,O(n)
  3. 局限性,需要一定辅助空间,牺牲空间换时间,适用于范围集中的数据

优化

思考

  1. 如果待排序记录中存在负数(无法实现)
  2. 如果待排序记录中最小为10000,最大为20000(存在较大的空间浪费)

解决(相对映射)

假设待排序记录中最小为10000,最大为20000,我们只需要10000个辅助空间即可(20000-10000),用0表示10000,10000表示20000。

void CountSort(int a[],int n) {
	//找出最小、最大值,确定临时数组大小 
	int min_=a[0],max_=a[0];
	for(int i=0;i<n;i++){
		if(min_>a[i]) min_=a[i];
		if(max_<a[i]) max_=a[i];
	}
	int tmp[max_-min_+1];//大小:最大值-最小值+1 
	memset(tmp,0,sizeof(tmp));//初始化为0
	for(int i=0; i<n; i++)
		tmp[a[i]-min_]++;//注意是相对映射(数据映射到下标时-min) 
	int index=0;
	for(int i=0; i<=max_-min_; i++)//覆盖回原数组
		if(tmp[i]!=0)
			while(tmp[i]--)
				a[index++]=i+min_;//恢复原数据需要+min 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用计数排序来对元素大小范围为[0,10]的10000容量数组进行排序计数排序是一种线性时间复杂度的排序算法,适用于元素范围较小且已知的情况。 首先,你需要创建一个长度为11的计数数组,用于统计每个元素的出现次数。数组下标对应元素的值,数组值对应该元素出现的次数。 接下来,遍历待排序数组,统计每个元素的出现次数,并将统计结果保存在计数数组中。 然后,根据计数数组元素的出现次数,重新构建已排序数组。遍历计数数组,将计数值不为0的元素按照计数值的大小,依次放入已排序数组中。 最后,已排序数组即为排序结果。 以下是一个示例代码,使用计数排序数组进行排序: ```python def counting_sort(arr): count = [0] * 11 # 创建计数数组,初始值都为0 sorted_arr = [0] * len(arr) # 创建已排序数组 # 统计每个元素的出现次数 for num in arr: count[num] += 1 # 重新构建已排序数组 index = 0 for i in range(len(count)): while count[i] > 0: sorted_arr[index] = i index += 1 count[i] -= 1 return sorted_arr # 测试排序 arr = [3, 5, 2, 1, 4, 4, 5, 3, 1, 2] sorted_arr = counting_sort(arr) print(sorted_arr) ``` 输出结果为:[1, 1, 2, 2, 3, 3, 4, 4, 5, 5] 请注意,这里假设待排序数组中所有元素都在范围[0, 10]之间。如果待排序数组中的元素超出了该范围,需要对计数数组的长度进行相应的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值