九大排序之——计数排序

计数排序


计数排序步骤:


(1)找出待排序的数组中最大和最小的元素;

(2)统计数组中每个值为i的元素的出现的次数,存入数组C的第i项;

(3)对所有的计数累加;

(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1;


图示:




代码实现:


void CountSort(int* arr, size_t n)
{
	assert(arr);
	int max = 0;
	for (size_t i = 0; i < n; i++)
	{
		if (arr[i]>max)
			max = arr[i];
	}
	//计数数组
	int* tmp = new int[max + 1];
	memset(arr, 0, sizeof(int)*(max + 1));
	for (size_t i = 0; i < n; i++)
	{
		tmp[arr[i]]++;
	}
	int index = 0;
	for (size_t i = 0; i <= max; i++)
	{
		while (tmp[i]--)
		{
			arr[index] = i;
			++index;
		}
	}
	delete[] tmp;
}


时间复杂度&空间复杂度&稳定性


时间复杂度:O(N+k)   ----k是要排序的数组的范围

空间复杂度:O(k)

稳定性:稳定


计数排序优化


类似于直接哈希算法,当数组中的元素不是从最小的数开始的,而是像(1000,1002,1003,1004,1000)这样的数组采用计数排序时,如果我们依旧是开辟最大数+1的空间时,就会使前面的空间全部浪费,因此应该找出最大值和最小值,两者相减就会得到对应的临时数组空间的大小,然后对其进行相应的映射,得到排好序的有序序列。


计数排序优化代码实现:


void CountSort(int* arr, size_t n)
{
	assert(arr);
	int max = arr[0];
	int min = arr[0];
	for (size_t i = 0; i < n; i++)
	{
		if (arr[i] > max)
			max = arr[i];
		if (arr[i] < min)
			min = arr[i];
	}
	//确定要开辟数组的大小
	int range = max - min + 1;
	int* tmp = new int[range];
	for (size_t i = 0; i < n; i++)
	{
		tmp[arr[i] - min]++;
	}
	//考回原数组
	int index = 0;
	for (size_t i = 0; i < range; i++)
	{
		while (tmp[i]--)
		{
			arr[index] = i + min;
			index++;
		}
	}
	delete[] tmp;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_happiness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值