1 概述
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
2 算法流程
- 找出待排序的数组中最大和最小的元素
- 统计数组中每个值为i的元素出现的次数,存入数组C(即容器)的第i项
- 根据容器计数结果重新填充目标数组,从小到大或从大到小,例如,计数了m个50就填充m个
3 代码/Python
def countingSort(arr, maxValue):
# 根据最大值来构建容器,初始化容器
bucketLen = maxValue+1
bucket = [0]*bucketLen
sortedIndex =0
arrLen = len(arr)
for i in range(arrLen):
# 容器计数,例如,出现50,则在第50个容器内加1
bucket[arr[i]]+=1
for j in range(bucketLen):
# 根据容器计数结果重新填充arr
while bucket[j]>0:
arr[sortedIndex] = j
sortedIndex+=1
bucket[j]-=1
return arr
# 算法调用
import random
nums = [random.randint(0,100) for i in range(10)]
print('随机生成10个数字:', nums)
print('排序后输出结果为:', countingSort(nums,100))
4 算法解释
- 当最大值 k k k不是很大并且序列比较集中时,计数排序是一个很有效的排序算法
- 时间复杂度:输入的元素是 n n n 个 0到 k k k 之间的整数时,两次遍历,一次是 n n n,一次是 k k k,时间复杂度是 O ( n + k ) O(n+k) O(n+k)
- 空间复杂度:使用的额外空间最少的情况是容器大小,就是 O ( k ) O(k) O(k),如果输出不覆盖原数组,开辟额外n空间,就是 O ( n + k ) O(n+k) O(n+k)
- 稳定性:在排序过程,作为存储容器可以不改变相等元素的位置,所以是稳定的