Fork me on GitHub

  计数排序假定输入元素的每一个都是介于0到k之间的整数,此处K为某个整数,当k=O(n)时,计数排序的运行时间为O(n)

它的基本思想是:根据每个输入元素x确定小于x的元素个数,根据这个信息把x直接放到它在最终输出数组中的特定位置上。

  通俗地理解,例如有10个年龄不同的人,统计出有8个人的年龄比A小,那A的年龄就排在第9位,用这个方法可以得到其他每个人的位置,也就排好了序。

当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去1的原因。算法的步骤如下:

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为k的元素出现的次数,存入数组C的第k
  3. 对所有的计数累加C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素k放在新数组的第C[k]项,每放一个元素就将C[k]减去1 

   该算法的python实现:

def _max(alist,flag):
        _max = alist[0]
        _min = alist[0]
        for iNum in alist:
                if iNum > _max:
                        _max = iNum
                if iNum < _min:
                        _min = iNum
          
        if True == flag:
                return _max
        if False == flag:
                return _min

def countingSort(arr,maxValue):
    bucketLen = maxValue+1
    bucket = [0]*bucketLen
    sortedIndex =0
    arrLen = len(arr) 
    for i in range(arrLen):
        if not bucket[arr[i]]:
            bucket[arr[i]]=0 
        bucket[arr[i]]+=1
    for j in range(bucketLen):
        while bucket[j]>0:
            arr[sortedIndex] = j
            sortedIndex+=1
            bucket[j]-=1
    return arr

a_list = [54,26,93,17,77,31,44,55,20]
print countingSort(a_list,_max(a_list,True))

  总结,该算法的运行时间极小,为O(n),但是所花费的空间就比较了,需要额外申请数组的内存,说白了,就是通过空间来换时间。

这种一般是在CPU主频比较小,内存又比较充足的情况下使用比较好。

posted on 2018-01-11 12:14  虚生  阅读(274)  评论(0编辑  收藏  举报