版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u012495579/article/details/86631204
以前自己的博客总是零零散散,学习的东西也有记录,但是没有归纳到一块儿,后来也就慢慢丢了。所以打算定期花点时间,把学习的东西整理一下,以便日后查阅。
基本思想
计数排序是一种有趣又扯淡的排序方法。
我们有已知数组A,需要将A中的元素排序(默认从小到大);
第一步:我们需要一个辅助数组B,B中任意元素有该特点:下标表示A中某元素的值,B中的值表示该元素在A中出现得到次数。即 B[i]=i在A中出现的次数 。
第二步:循环输出B数组,输出规则为:当某元素a(下标为b)的值非零时,输出a个b;
该排序方法其实利用了数组下标的递增性进行排序,但是这样的方法有很大局限性。首先,值需要表示为下标,则只能用于整数的排序,其次,如果A中的值稀疏且巨大,则B数组的空间也会有很大浪费。如:A中数为1000000,则B数组长度至少要超过该值。
算法实现
首先是一个简易的生成指定个随机数的算法,文件命名data.py:
import random
# 生成num位随机数
def get_data(num):
arr = []
for i in range(0, num):
arr.append(random.randint(0, 99))
return arr
下面是用Python完成的计数排序算法:
import data
A = data.get_data(1000)
def counting_sort (arr):
# 确定最大值(用于确定数组B的长度)
max = -10000
for i in arr:
if i > max:
max = i
# 生成最大值位的数组B,元素值初始化为0
B = [0] * (max + 1)
# 用数组B记录元素在A中出现的次数
for i in arr:
B[i] += 1
# 循环展开B
arr = []
index = 0
for i in B:
if i != 0:
p = i
while p >= 0:
arr.append(index)
p -= 1
index += 1
return arr
print(counting_sort(A))
复杂度分析
该算法我们可以看到主要的时间花费应该是在展开B数组获取排序后的值时,首先我们循环了B数组的长度次,即最大值。然后在找到非零值时又进行了循环确定元素出现的次数,该循环总和为A的长度。
所以T(n) = O(n+k),n为元素个数,k为最大值。