排序算法 - 计数排序

计数排序(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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值