计数排序

《算法导论》第八章 线性时间排序中的计数排序,解决的问题是:当需要排序的数组中最大值在一定范围内,比如,数组A中的数都是小于等于20的数值,那么,我们可以通过,创建一个数组C大小于21。把A中的数值a当作C数组的下标i,而此下标i处存储的值是A数组中的a,即C[a] = a在A数组中的个数。这样C数组下标i之前的所有个数相加就是a排序后应该处的位置。当然,再考虑上有重复的情况下,C数组下标i之前的所有元素相加,再加上i处的值,就是a排序后存在的最后一个位置,如果有重复就往这个位置前面放。


描述起来不太直观,下面通过Python的实现来说明:

如果不清楚,通过查看打印出来的结果,很容易明白其中的原理。计数排序应该是所有排序中最简单的

import random

A = [random.randint(0, 9) for i in range(20)]   #A是我们待排序的数组
B = [0 for i in range(20)]                      #B是存放排好序的数组,暂时初始化成0
#B = [0] * 20   这样是不是更Python?

#C是存放数组中元素个数的数组,因为A数组中的数据是从0-9,所以这里C的大小使用10
C = [0 for i in range(10)]

def counting_sort(A, B, C):
    lengthA = len(A)
    lengthC = len(C)
    
    #这里使用A[i]中的元素当作C数组的下标,并在C[A[i]]中存储A[i]在A中的个数
    for i in range(0, lengthA):
        C[A[i]] = C[A[i]] + 1
    print C
    
    #因为使用A[i]当作下标,所以C[i]前面的元素个数就是A[i]排序后,应该处在的位置
    for i in range(1, lengthC):
        C[i] = C[i] + C[i-1]
    print C
    
    #C[A[i]] - 1就是排序后A[i]应该在B上的下标,减1是因为我们的数组是从0开始的,而C[A[i]]是元素个数。
    for i in range(0, lengthA)[::-1]:
        B[C[A[i]]-1] = A[i]
        C[A[i]] = C[A[i]] - 1        #这里是因为如果有重复的话,
        、                           #再存储的时候就应该存在上一个相同元素的前面

counting_sort(A, B, C)

你可能感兴趣的:(计数排序)