Python实现计数排序

Python实现计数排序

一、计数排序简介

计数排序(Counting Sort)是一种不比较数据大小的排序算法,是一种牺牲空间换取时间的排序算法。

计数排序适合数据量大且数据范围小的数据排序,如对人的年龄进行排序,对考试成绩进行排序等。

计数排序先找到待排序列表中的最大值 k,开辟一个长度为 k+1 的计数列表,计数列表中的所有初始值都为 0。走访待排序列表,如果走访到的元素值为 i,则计数列表中索引 i 的值加1,走访完整个待排序列表,就可以统计出待排序列表中每个值的数量。然后创建一个新列表,根据计数列表中统计的数量,依次在新列表中添加对应数量的 i ,得到排好序的列表。

二、计数排序原理

计数排序的原理如下:

1. 找到待排序列表中的最大值 k,开辟一个长度为 k+1 的计数列表,计数列表中的值都为 0。

2. 走访待排序列表,如果走访到的元素值为 i,则计数列表中索引 i 的值加1。

3. 走访完整个待排序列表,计数列表中索引 i 的值 j 表示 i 的个数为 j,统计出待排序列表中每个值的数量。

4. 创建一个新列表,遍历计数列表,依次在新列表中添加 j 个 i,新列表就是排好序后的列表,整个过程没有比较待排序列表中的数据大小。

以列表 [5, 7, 3, 7, 2, 3, 2, 5, 9, 5, 7, 6] 进行升序排列为例。列表的初始状态如下图。

1. 待排序列表中的最大值为9,所以开辟一个长度为10的计数列表,索引为0~9,值全为0。

2. 走访待排序列表,如果走访到的元素值为 i,则计数列表中索引 i 的值加1。第一个元素值为5,计数列表中索引5的值加1,从0变为1。

3. 第二个元素值为7,计数列表中索引7的值加1,从0变为1。

4. 第三个元素值为3,计数列表中索引3的值加1,从0变为1。

5. 第四个元素值为7,计数列表中索引7的值加1,从1变为2。

6. 重复走访完整个待排序列表,所有元素的个数都统计到了计数列表中。

7. 创建一个新列表,遍历计数列表,依次在新列表中添加对应数量的元素。0和1都是0个,不需要添加,2有两个,在新列表中添加两个2。添加后计数列表中减掉对应的数量。

8. 3有两个,继续在新列表中添加两个3。添加后计数列表中减掉对应的数量。

9. 遍历整个计数列表,添加完所有的数据,新列表就是排序完成后的列表。排序结果如下图。

三、Python实现计数排序

# coding=utf-8
def counting_sort(array):
    if len(array) < 2:
        return array
    max_num = max(array)
    count = [0] * (max_num + 1)
    for num in array:
        count[num] += 1
    new_array = list()
    for i in range(len(count)):
        for j in range(count[i]):
            new_array.append(i)
    return new_array


if __name__ == '__main__':
    array = [5, 7, 3, 7, 2, 3, 2, 5, 9, 5, 7, 6]
    print(counting_sort(array))

运行结果:

[2, 2, 3, 3, 5, 5, 5, 6, 7, 7, 7, 9]

代码中,使用Python内置函数max()求出待排序列表中的最大值。然后根据上面分析的排序原理,进行计数,再将数据添加到新列表中。i 表示计数列表的索引,也表示待排序列表中值为 i 的元素,j 表示值为 i 的元素有 j 个。

四、计数排序的时间复杂度和稳定性

1. 时间复杂度

在计数排序中,需要走访待排序列表中的每一个元素,进行计数,列表长度为 n ,然后需要遍历计数列表,添加数据到新列表中,计数列表长度为 k+1 ,时间复杂度为 T(n)=n+k+1,再乘计数和添加数据的步骤数(常数,不影响大O记法),所以计数排序的时间复杂度为 O(n+k) 。

2. 稳定性

根据计数排序的应用场景,待排序列表中有很多值相等的元素。不过,计数排序没有比较待排序列表中的数据大小,也没有进行位置交换,相等数据的相对次序是保持不变的。所以计数排序是一种稳定的排序算法。

猜你喜欢

转载自blog.csdn.net/weixin_43790276/article/details/107398262