互联网行业的小白,写博客的目的是为了记录自己的学习过程、对自己学习中所犯的错误做一个总结。由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!
1. 原理
计数排序是一个非基于比较的排序算法,它的优势在于在对一定范围内的整数排序时,它的复杂度为 O ( n + k ) Ο(n+k) O(n+k)(k是整数的范围),快于任何比较排序算法。其思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。
2. 步骤
- 找出序列中最大值和最小值,开辟Max-Min+1的辅助空间
- 扫描一遍原始序列,以当前值 - Min作为下标,将该下标的计数器加1
- 扫描一遍计数器序列,按顺序把值收集起来
3. 演示
4. 模板
C语言
void countingsort(int *Array, int size_A){
int Max = Array[0]; // 序列的最大值
int Min = Array[0]; // 序列的最小值
for(int i = 0; i < size_A; i++){
if(Array[i] >= Max) Max = Array[i];
if(Array[i] <= Min) Min = Array[i];
}
int Range = Max - Min + 1; // 临时开辟辅助空间的大小
int* temp = new int[Range]; // 动态开辟空间大小为Range的temp序列
memset(temp, 0, sizeof(int) * Range); //初始化
for(int i = 0; i < size_A; i++)
temp[Array[i] - Min] += 1; // 当前值 - Min 作为下标的计数
int index = 0; // 控制变量
for(int i = 0; i < Range; i++){ // 遍历辅助空间
while(temp[i]--){ // 下标处的数值是几,说明该数出现了几次
Array[index++] = i + Min; // 将下标处的数对应回原序列
}
}
delete[] temp; // 回收空间
}
python版
def countingSort(Array):
Max = max(Array) # 序列的最大值
Min = min(Array) # 序列的最小值
Range = Max - Min + 1 # 临时开辟辅助空间的大小
temp = [0] * (Range) # 开辟辅助空间
for i in range(len(Array)):
temp[Array[i] - Min] += 1 # Array[i] - Ain是将该数对应到辅助空间的下标
index = 0 # 控制变量
for i in range(0, Range): # 遍历辅助空间
while(temp[i] > 0): # 下标处的数值是几,说明该数出现了几次
Array[index] = i + Min # 将下标处的数对应回原数组
index += 1
temp[i] -= 1
return Array
5. 分析
-
计数排序是一种以空间换时间的排序算法,并且只适用于待排序列中所有的数较为集中时。如序列[3, 2, 1, 999]就不适用于计数排序,需要开辟1000个辅助空间,太过于浪费。
-
计数排序是稳定的:具有相同值的两个元素在输出数组中的相对次序与它们在输入数组中的相对次序相同。也就是说,对两个相同的数来说,在输入数组中先出现的数,在输出数组中也位于前面。
-
计数排序经常被作为基数排序算法的一个子过程。
码字不易,您的
支持
就是我坚持
下去的动力,一起加油哦。