一、基本原理
计数排序的思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。
- 找出序列中最大值和最小值,开辟Max-Min+1的辅助空间
- 最小的数对应下标为0的位置,遇到一个数就给对应下标处的值+1,。
- 遍历一遍辅助空间,就可以得到有序的一组序列
限制:计数排序假设n个输入元素中的每一个元素都是在0到k区间内的一个整数,只可处理非负数;计数排序的基本思想:对每一个元素x,确定小于x的元素个数,利用这一信息,就可以直接把x放到输出排序数组的正确位置上了。

二、图解排序过程

三、实现代码
import random
def count_sort(li,max_num = 100):
count = [0 for i in range(max_num+1)]
for num in li:
count[num] += 1
li.clear()
for i,val in enumerate(count):
for _ in range(val):
li.append(i)
li = [random.randint(0, 100) for i in range(100000)]
count_sort(li)
print(len(li))
打印结果
"C:Program FilesPython35python.exe" E:/count.py
100000
Process finished with exit code 0
四、性能分析
1、和系统自带的速度比较
import random
import time
import copy
import sys
from collections import deque
def cal_time(func):
def wrapper(*args, **kwargs):
t1 = time.time()
result = func(*args, **kwargs)
t2 = time.time()
print("%s running time: %s secs." % (func.__name__, t2 - t1))
return result
return wrapper
@cal_time
def count_sort(li,max_num = 100):
count = [0 for i in range(max_num+1)]
for num in li:
count[num] += 1
li.clear()
for i, val in enumerate(count):
for _ in range(val):
li.append(i)
@cal_time
def sys_sort(li):
li.sort()
li = [random.randint(0, 100) for i in range(100000)]
li1 = copy.deepcopy(li)
count_sort(li)
sys_sort(len(li))
输出结果
"C:Program FilesPython35python.exe" E:/python/test/count.py
count_sort running time: 0.018001079559326172 secs.
Traceback (most recent call last):
File "E:/工作目录/python/test/count.py", line 35, in <module>
sys_sort(len(li1))
File "E:/工作目录/python/test/count.py", line 10, in wrapper
result = func(*args, **kwargs)
File "E:/工作目录/python/test/count.py", line 29, in sys_sort
li.sort()
AttributeError: 'int' object has no attribute 'sort'
Process finished with exit code 1
2、算法分析:
计数排序是一种以空间换时间的排序算法,并且只适用于待排序列中所有的数较为集中时,比如一组序列中的数据为0 1 2 3 4 999;就得开辟1000个辅助空间。
3、时间复杂度
- 时间复杂度:O(n)O(n)
- 空间复杂度:O(n)+O(N)O(n)+O(N)
- 是否稳定:是
- 优化措施:为了保障稳定性,算法中进行了多余的操作,如果不需要稳定性,可以优化时间。
4、应用场景
计数排序虽然时间复杂度较低,但需要满足的条件较多,如果能满足限制条件与空间需求,计数排序自然很快
1、计数排序的时间度理论为O(n+k),其中k为序列中数的范围。
2、不过当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如归并排序,堆排序)
