问题:
假设数组里有20个随机整数,取值范围从0到10,要求用最快的速度把这20个整数从小到大排序。
看到问题的第一反应是快排,然后想想不对,它的分布从0到10一共11个数,用计数排序更快。
什么时候不用计数排序?
所以当数组最大最小值差远小于数组长度时,使用计数排序更快。
#数组a为随机数组
a = [4, 8, 1, 9, 9, 1, 6, 0, 10, 2, 2, 0, 0, 7, 10, 10, 0, 5, 8, 2]
def cntsort(arr):
nums = [0 for _ in range(11)]
for i in arr:
nums[i] += 1
res = []
for i in range(len(nums)):
res += [i] * nums[i]
return res
print(cntsort(a))
当然,此时是有问题的,如果数组里最小值是90,最大值是100呢?那么开的0到89个数组就白开了
解决方法,先遍历一遍输入数组,记录其最大最小值,当然根据实际情况手动设计合理的区间范围,效果更好
a = [98, 100, 96, 97, 98, 93, 98, 96, 95, 95, 95, 96, 90, 99, 94, 90, 90, 91, 98, 98]
def cntsort(arr):
max,min = arr[0],arr[0]
for i in arr:
if i > max:max = i
if i < min:min = i
l = max - min
nums = [0 for _ in range(l+1)]
for i in arr:
nums[i - min] += 1
res = []
for i in range(len(nums)):
res += [min + i] * nums[i]
return res
print(cntsort(a))
总结:其时间复杂度为O(n),比快排O(nlogn)在某些场景下效果更好,如给5W员工按年龄排序。