编程小白最近在学习算法,自己用python写了十大排序算法,发出来供大家参考。如有不足之处,欢迎批评讨论。
第四是两种桶排序:计数排序和桶排序。
def countingSort(nums: list) -> list:
"""
计数排序
### 改进建议
1. **内存使用优化**:当前算法中用`sum(..., [])`来拼接子列表。对于较大的数组,这种方法可能会导致较高的内存消耗。可以使用`itertools.chain.from_iterable`来减少内存使用。
:param nums:待排序序列
:return:排序后序列
"""
if not nums: return [] # 检查是否为空列表
countingDict = {key: 0 for key in range(min(nums), max(nums) + 1)} # 为所有在输入数组中出现的数字创建一个计数字典。范围从数组中的最小值到最大值。
# 遍历输入数组,统计每个数字的出现次数。
for num in nums:
countingDict[num] += 1
# 基于计数字典,构建排序后的数组。利用列表生成式创建数值重复的列表,然后将这些子列表拼接成一个完整的排序数组。
# 'sum'函数在这里用于拼接所有的子列表,并使用初始值[]以保证结果是一个列表。
return sum([[key] * val for key, val in countingDict.items()], [])
def bucketSort(nums: list, fMap: 'function', fSort: 'function') -> list:
"""
桶排序
:param nums:待排序序列
:param fMap:将 nums 映射到多个桶中的函数
:param fSort:桶内排序的函数
:return:排序后序列
"""
mappedNums = fMap(nums) # 使用 fMap 函数将 nums 映射到多个桶中。
# 遍历每个桶,并使用 fSort 函数对每个桶内的元素进行排序。
for i, bucket in enumerate(mappedNums):
mappedNums[i] = fSort(bucket)
return sum(mappedNums, []) # 合并所有桶中的元素,并返回最终排序的列表。
def fMap(nums: list) -> list:
"""映射函数可自定义,以下用等距分隔"""
step = 10 # 定义步进值,用于将数字分配到不同的桶。
bucketNum = max(nums) // step + 1 # 计算所需桶的数量。
bucket = [[] for i in range(bucketNum)] # 初始化桶。
# 将每个数字分配到对应的桶中。
for num in nums:
bucket[num // step].append(num)
return bucket
def fSort(nums: list) -> list:
"""桶内排序函数可自定义,以下用计数排序"""
return countingSort(nums)
if __name__ == '__main__':
from random import choices
nums = list(choices(range(100), k=10)) * 2
print('Before sorting:', nums)
print('After countingSort sorting:', countingSort(nums))
print('After bucketSort sorting:', bucketSort(nums, fMap, fSort))
输出:
Before sorting: [64, 0, 0, 20, 71, 6, 49, 50, 31, 96, 64, 0, 0, 20, 71, 6, 49, 50, 31, 96]
After countingSort sorting: [0, 0, 0, 0, 6, 6, 20, 20, 31, 31, 49, 49, 50, 50, 64, 64, 71, 71, 96, 96]
After bucketSort sorting: [0, 0, 0, 0, 6, 6, 20, 20, 31, 31, 49, 49, 50, 50, 64, 64, 71, 71, 96, 96]