计数排序算法

概念及其介绍:

通过统计序列中各个元素出现的次数,完成对整个序列的升序或降序排序。

算法思想:
  • 先遍历整个数组(arr[N]),然后找到整个数组中最大的那个元素max,然后创建一个max+1大小的数组(讲解为input[max])和一个与原数组大小一样的数组(讲解为output[N])(最后会进行拷贝)
  • 以数组arr中的元素作为数组input中的下标,统计arr中元素出现的次数,然后以该元素为下标将元素出现的次数存储在数组input中
  • 进一步加工数组input中的元素,按照公式input[ i ] = input[ i ] + input[ i -1] ,修改数组input中的数据
  • 数组arr中的元素为下标对应在input数组中的元素的值,其值减1作为数组output的下标,将数组arr此时对应的值存放在改下标对用的数组output中(这里可能有点绕,但是多看几遍就应该能理解)
  • 最后一步,即将数组output中的元素值对应拷贝到数组arr中。在答应出来即可。
算法过程演示:

1) 找到序列中的最大值(用 max 表示)。对于 {4, 2, 2, 8, 3, 3, 1} 序列来说,最大值是 8。
 

2) 创建一个长度为 max+1、元素初值全部为 0 的数组(Python 中可以使用列表),为数组中 [1,max] 区域内的各个空间建立索引:
找到序列中的最小值(用 min 表示),作为数组下标为 1 的存储空间的索引;

待排序的元素都是整数,可以直接将数组下标作为各个存储空间的索引,如下图所示。
 

 3)统计待排序序列中各个元素的出现次数,存储到以该元素为索引的数组空间中。例如,待排序序列中元素 2 出现了两次,所以索引(下标)为 2 的数组空间中存储 2 。更新后的数组如下图所示:
 

 4) 进一步加工数组中存储的数据。从数组下标为 1 的位置开始,按照公式修改数组中存储的元素

其中 i 的取值范围是 [1, max],修改后的数组为:
 

5) 遍历待排序列中的元素,以该元素为索引获取数组中存储的值,此值即为序列排序后元素应处的位置。

举个例子,序列中第一个元素是 4,数组中索引 4 对应的值为 6,因此序列排序后元素 4 位于第 6 的位置处,如下图所示:
 

 代码示例:
#define SE 9
//查找出数组最大值
int getmax(int arr[],int n)
{
	int i = 0;
	int max = arr[0];
	for (i = 0; i < n; i++)
	{
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	return max;
}
//计数排序
void the_counting_sort(int arr[])
{
	//首先找到数组中的最大值
	int max = getmax(arr, SE);
	//然后创建一个max+1长度的数组和一个输出拷贝数组
	int input[MAX] = { 0 };
	int output[SE] = { 0 };
	//统计待排序序列中各个元素的出现次数,存储到以该元素为索引的数组空间中
	for (int i = 0; i < SE; i++)
	{
		//以待排序序列中的元素为下标存储数据,
		//当arr数组中重复出现同一个元素的时候,以该元素为下标的input数组中的相应的元素加1
		input[arr[i]]+= 1;
	}
	
	//进一步加工数组中存储的数据.利用公式进行修改数组input中的元素值
	for (int i = 1; i <= SE; i++)
	{
		input[i] = input[i] + input[i - 1];
	}
	//遍历待排序列中的元素,以该元素为索引获取数组input中存储的值,此值即为序列排序后元素应处的位置
	for (int i = 0; i < SE; i++)
	{
		output[input[arr[i]] - 1] = arr[i];
		//当确定了一个元素排序后的位置,需要将数组中该元素为索引对应的值减去 1
		input[arr[i]]--;
	}
    //进行拷贝,将数组output中的元素值拷贝到数组arr中,然后再打印arr即可
	for (int i = 0; i < SE; i++)
	{
		arr[i] = output[i];
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

遇见陌生人了

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

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

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

打赏作者

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

抵扣说明:

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

余额充值