基本算法之桶排序(Bucket Sort)
基本算法—08、桶排序(Bucket Sort)算法
。往期请看选择排序,插入排序,归并排序,快速排序等等都发布的!欢迎大家批评指正!
0、前言
评判一个算法的好坏的标准:
- 时间复杂度
- 空间复杂度
1、桶排序算法是什么?
实现思想/实现步骤:
1.设置一定量的数组当做空桶(一般情况设置五个)
2.遍历输入数据,把数据一个一个的放到对应的桶里面
3.对每一个非空的桶进行排序(可以直接调用其他的排序方法)
4.对不是空的桶里面排序好的数据进行拼接
桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。
为了使桶排序更加高效,我们需要做到这两点:
- 在额外空间充足的情况下,尽量增大桶的数量
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
什么时候最快(Best Cases):
当输入的数据可以均匀的分配到每一个桶中
什么时候最慢(Worst Cases):
当输入的数据被分配到了同一个桶中
2、算法过程图解
3、代码实现
代码如下(示例):
"""
Busket Sort 桶排序
是计数排序的升级
桶排序主要是对现有的数组分组,然后利用其它排序方法进行每组的分别排序,
最后把分组排序好的,组合在一起就是最后的答案了
时间复杂度:O(n+k)
n:数据规模
k:“桶”的个数
"""
# 插入排序的算法
def insertion_sort(alist):
for i in range(1,len(alist)):
# 循环子序列的时候,就要反着来!
for j in range(i,0,-1):
# 如果后面一个数,大于前面的一个数,就交换位置
if alist[j]<alist[j-1]:
alist[j],alist[j-1]=alist[j-1],alist[j]
return alist
# 桶排序
def bucketSort(nums, defaultBucketSize = 5):
maxVal, minVal = max(nums), min(nums)
# 如果没有指定桶的大小,则默认为5
bucketSize = defaultBucketSize
# 数据分为 bucketCount 组,这一个是根据每组的数量决定的
bucketCount = (maxVal - minVal) // bucketSize + 1
buckets = [[] for i in range(bucketCount)] # 二维桶
# 利用函数映射将各个数据放入对应的桶中
for num in nums:
buckets[(num - minVal) // bucketSize].append(num)
nums.clear() # 清空 nums
# 对每一个二维桶中的元素进行排序
for bucket in buckets:
insertion_sort(bucket) # 假设使用插入排序
nums.extend(bucket) # 将排序好的桶依次放入到 nums 中
return nums
if __name__ == '__main__':
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print(f'桶排序(Bucket Sort)之前原列表的顺序:{alist}')
alist = bucketSort(alist)
print(f'桶排序(Bucket Sort)之后的列表的顺序:{alist}')
print(f'桶排序(Bucket Sort)之后的正确的顺序:[17, 20, 26, 31, 44, 54, 55, 77, 93]')
大家可以把代码放置到编译器里面,debug运行,看一哈具体的过程,结合动态图片演示理解更好!
4、评判算法
- 最好时间复杂度:O(n+k)
- 最坏时间复杂度:O(n2)
- 平均时间复杂度:O(n+k)
- 空间复杂度:O(n+k)
- 算法稳定性:稳定的排序