前言
和前面说的冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序,希尔排序相比,它们都是比较排序,在排序的过程中,都需要进行元素之间的比较,而今天的计数排序就不需要了。
思路
通过名称可以知道它的核心体现在计数,其实就是记录每一个数字出现的频率,但是得提前确定所有数字的区间,即得知道最大值和最小值,才能保证不会有遗漏。
举例
这里给出的需要排序的列表是:[1,2,6,2,3,1,4,4,5],所以最大值是6,最小值是1
我在这里从0开始,依次列出区间内所有的数字,即:0,1,2,3,4,5,6(并设定每个数字出现的次数为0),然后依次遍历需要排序的列表,如果某个数字出现一次,就让它的出现次数加一,直到遍历完整个列表。
最后,从小到大,按照每个数字出现的次数依次添加到新列表中,即排序完成。
源码
# -*- coding: UTF-8 -*-
'''
*****************LLL*********************
* @Project :排序算法
* @File :lll10_计数排序.py
* @IDE :PyCharm
* @Author :LLL
* @Date :2022/5/4 11:56
*****************************************
'''
from random import randint
from tools import clocked
@clocked
def count_sort(li, max_val=100):
# 创建一个[0,max_val]的列表,相应的位置存储该数出现的次数
count_li = [0 for i in range(max_val + 1)]
'''
依次遍历列表:[1,2,6,2,3,1,4,4,5]
出现的次数 次数 次数 次数 次数 次数 次数 次数 次数
min_val: 0: 0 0: 0 0: 0 0: 0 0: 0 0: 0 0: 0 0: 0 0: 0
1: 1 1: 1 1: 1 1: 1 1: 1 1: 2 1: 2 1: 2 1: 2
2: 0 2: 1 2: 1 2: 2 2: 2 2: 2 2: 2 2: 2 2: 2
3: 0 ---> 3: 0 ---> 3: 0 ---> 3: 0 ---> 3: 1 ---> 3: 1 ---> 3: 1 ---> 3: 1 ---> 3: 1 ---> [1,1,2,2,3,4,4,5,6]
4: 0 4: 0 4: 0 4: 0 4: 0 4: 0 4: 1 4: 2 4: 2
5: 0 5: 0 5: 0 5: 0 5: 0 5: 0 5: 0 5: 0 5: 1
max_val: 6: 0 6: 0 6: 1 6: 1 6: 1 6: 1 6: 1 6: 1 6: 1
'''
# 计算每个数出现的次数
for i in li:
count_li[i] += 1
# 依次添加到新的列表中
li.clear() #清空列表
for val, count in enumerate(count_li):
for i in range(count):
li.append(val)
if __name__ == '__main__':
li = [randint(1, 100) for i in range(100)]
max_val = max(li)
count_sort(li, max_val)
print(li)
同步更新于个人博客系统:计数排序——最简单的排序方式,没有之一?