【排序算法】计数排序(CountSort)

一、定义

        计数排序(CountSort)是一种非比较的排序,它的优势在于在对一定范围内整数排序时,它的时间夫扎渡为为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。 这是一种通过空间换取时间的算法,但是当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如归并排序,、堆排序、快速排序)✨

 

 二、思路:

1、确定范围,找出待排序数组✨ a[] 的最大值(max)和最小值(最小值)

2、申请一个计数的数组记为 ✨count[]并初始化为0,数组的大小由max-min+1决定(因为可以保证待排序所有的数都能记录上)🤔计数数组是什么个意思呢??🤔就是说我的计数数组,它的下标表示的是该值,然后,下标对应的元素表示该值在待排数组出现的次数✨

 3、计数:遍历待排序的数组,进行计数,对于每个元素 x ,我们将count[x-min]的值加1,表示在原数组中值为x的元素出现了count[x-min]次;👉👉看看下面呗🥰

用当前元素 x - min 这样是为了进行相对映射,🤔因为我们数组的下标从0开始的,但是数据并不一定是从0开始的,如果我直接就是将 x的值作为计数数组的下标,就会造成空间浪费的现象。用x-min的方式,可以将其记录在对应下标的位置处

4、排序:当遍历完待排序数组后,计数数组也就记录好数据了🐸🐸

✨那么也就最后一步了,排序嘛,遍历计数数组,根据每个下标对应的数据个数排序,通过计数将元素一一放入到数组a[] 中,注意是下标加min  因为之前是 小标是 x- min 计数的 放到a[],就是下标j+min;该下标对应的元素有几个 就对该下标放几次;因为这里都是只有一个的情况,所以我们都只放了一次,因为原数组没有 6 为0,所以没有放入

 注意:计数排序只适用于整数,而且尽量是数据集中的,但是如果数据过于离散的话(数据范围很大)创建和维护数组需要消耗大量内存,那么此时该排序就未必好用了

三、时间复杂度:

时间复杂度 O(N+k)  取决于k 与 N 谁大

空间复杂度 O(k) 取决于max-min+1的大小 

✨补充一句:它是稳定的,相等的元素在排序后的相对顺序不会改变✨

四、代码实现:

//计数排序:
void CountSort(int* a, int n)
{

	//求最大和最小值
	int max = a[0];
	int min = a[0];
	for (int i = 1; i < n; i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int ragem = max - min + 1;
	//计数的数组
	int* count = (int*)calloc(ragem, sizeof(int));;
	if (count == NULL)
	{
		perror("calloc fail");
		return;
	}
	//计数
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}
	int j = 0;
	//排序
	for (int i = 0; i< ragem; i++)
	{
		while (count[i]--)
		{
			a[j++] = i+ min;
		}
	}

}

 ✨可以看一下,对1000万个数据进行排序,五种排序消耗的时间,计数是👉真的快

🧑‍🎓所以说在数据范围不是很大的情况下,计数快于需要进行比较的排序,真不是吹的 🤔

         拜  拜  喽     

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 计数排序是一种非比较排序算法。它的基本思想是对于给定的输入序列中的每一个元素,确定该元素在输入序列中的出现次数。然后根据出现次数对所有元素进行排序。 下面是一个示例JS代码: ``` function countSort(arr) { var max = Math.max.apply(null, arr); var min = Math.min.apply(null, arr); var count = new Array(max - min + 1).fill(0); for (var i = 0; i < arr.length; i++) { count[arr[i] - min]++; } var index = 0; for (var i = min; i <= max; i++) { while (count[i - min]-- > 0) { arr[index++] = i; } } return arr; } ``` 请注意,此代码只能用于整数数组,并且需要额外的空间来存储计数数组。 ### 回答2: 计数排序Counting Sort)是一种线性时间复杂度的排序算法,适用于待排序的数值范围较小的情况。该算法通过统计每个元素出现的次数,然后依次输出,实现排序的目的。 下面是一个使用JavaScript实现计数排序算法的例子: ```javascript function countingSort(arr) { let len = arr.length; if (len <= 1) { return arr; } // 找出待排序数组的最大值 let max = arr[0]; for (let i = 1; i < len; i++) { if (arr[i] > max) { max = arr[i]; } } // 创建一个计数数组,其中索引表示待排序元素值,值表示元素出现次数 let countArr = new Array(max + 1).fill(0); // 统计每个元素出现的次数 for (let i = 0; i < len; i++) { countArr[arr[i]]++; } // 对计数数组进行累加 for (let i = 1; i <= max; i++) { countArr[i] += countArr[i - 1]; } // 创建一个临时数组,存储排序后的结果 let tempArr = new Array(len); for (let i = len - 1; i >= 0; i--) { let value = arr[i]; let index = countArr[value] - 1; tempArr[index] = value; countArr[value]--; } // 将临时数组复制到原数组中 for (let i = 0; i < len; i++) { arr[i] = tempArr[i]; } return arr; } // 测试例子 let arr = [5, 8, 2, 1, 9, 5, 3, 3]; let sortedArr = countingSort(arr); console.log(sortedArr); // [1, 2, 3, 3, 5, 5, 8, 9] ``` 以上是一个简单的计数排序算法的JavaScript实现。希望对你有帮助! ### 回答3: 计数排序是一种非比较性的排序算法,它通过统计数组中每个元素出现的次数,进而确定每个元素的位置,从而实现排序。 以下是一个使用 JavaScript 实现的计数排序算法: ```javascript function countingSort(arr) { // 找出数组中的最大值和最小值,确定计数数组的大小 let max = Math.max(...arr); let min = Math.min(...arr); // 初始化计数数组 let counts = new Array(max - min + 1).fill(0); // 统计元素出现的次数 for (let i = 0; i < arr.length; i++) { counts[arr[i] - min]++; } // 根据计数数组重新排列原数组 let sortedArr = []; for (let i = 0; i < counts.length; i++) { while (counts[i] > 0) { sortedArr.push(i + min); counts[i]--; } } return sortedArr; } // 测试 let arr = [8, 2, 4, 9, 3, 6, 5, 1, 7]; let sortedArr = countingSort(arr); console.log(sortedArr); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` 以上代码实现了计数排序算法。首先,找出数组中的最大值和最小值,确定计数数组的大小。然后,初始化计数数组,统计每个元素出现的次数。接下来,根据计数数组重新排列原数组,并返回排序后的数组。 计数排序的时间复杂度为 O(n + k),其中 n 是待排序数组的长度,k 是待排序数组中的最大值和最小值的差。计数排序是一种稳定排序算法,适用于对一定范围内的整数进行排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值