一、介绍
桶排序,实际上是用二维数组实现的排序算法,它和计数排序一样也是线性时间的排序算法,它里面的桶就像上一篇文章里面计数排序中用到的count_list一样,只不过在桶排序当中我需要建立很多个count_list来辅助我的数据处理
那桶排序当中的桶(bucket)到底是什么意思?
每一个桶,都是一个有一定范围的一维数组,里面可以承载多个元素
举个例子,比如生成一个随机小数位的浮点数
[4.712924, 8.34, 2.341, 8.584, 0.061, 9.541, 2.791, 5.4803]
接下来就是要创建桶了,具体创建多少个桶,以及桶中的区间范围的确定有很多不同的方式,在这里我们采取数列中有多少个元素,我们就创建多少个桶,区间的范围我们用(最大值 - 最小值)/(桶的数量 - 1)
上面的列表长度一共是8 ,那么就先创建8个桶,每一个桶都有一个固定且合适的范围
元素值 | ||||||||
---|---|---|---|---|---|---|---|---|
桶序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
区间 | [0.61,1.45) | [1.45,2.769) | [2.769,4.123) | [4.123, 5.447) | [5.447, 6.831) | [6.831,8.185) | [8.185, 9.539) | [9.539, 9.541] |
创建好之后,就按照列表当中元素的顺序依次找到对应的桶,放进去即可
元素值 | 0.061 | 2.341 | 2.791 | 4.712924 | 5.4803 | 8.34 8.584 | 9.541 | |
---|---|---|---|---|---|---|---|---|
桶序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
区间 | [0.61,1.45) | [1.45,2.769) | [2.769,4.123) | [4.123, 5.447) | [5.447, 6.831) | [6.831,8.185) | [8.185, 9.539) | [9.539, 9.541] |
放好之后,对每个桶内的元素进行排序即可,如果顺序是已经排好了的,或者桶内只有一个元素,那么就不要排序了,直接遍历所有的桶,依次输出所有元素即可,这样就实现了排序的效果
[0.061, 2.341, 2.791, 4.712924, 5.4803, 8.34, 8.584,9.541]
二、具体代码实现
前期还是,创建具有一般性的随机浮点数组。
在这段代码当中为了数组能更好的符合这样的要求,我做了适当的处理,在每次生成浮点数的时候加上了位数的随机控制,这样各种位数的数字就有了
import random
array_list = []
def create_random_list():
'''
控制产生随机数列表
:return: array_list
'''
global num, start, end
num = int(input('请输入产生数组的个数:'))
if num <= 0:raise Exception('请输入大于零的数字')
start = int(input('请输入起始数字:'))
end = int(input('请输入结束数字:'))
if start > end :raise Exception('起始数字一定要小于结束数字')
for i in range(num):
# 控制小数点后的位数
temp = random.randint(1,6)
n = random.uniform(start, end) # 产生
array_list.append(round(n, temp)) # 随机保留小数点后的位数
return array_list
array_list = create_random_list()
print("生成的随机数组:\n%s"% array_list)
有了数组之后,就可以进行排序了
def bucket_sort(array_list):
# 先求出列表当中的最大最小值,帮助确定每个桶的区间范围
max_v = array_list[0]
min_v = array_list[0]
for i in range(len(array_list)):
if array_list[i] > max_v:
max_v = array_list[i]
if array_list[i] < min_v:
min_v = array_list[i]
# 求数列中的数值跨度
difference_value = max_v - min_v
# 根据数列的规模,去创建相应个数的桶,也就是二维数组
bucket_size = len(array_list)
bucket_list = []
for i in range(bucket_size):
bucket_list.append([])
# 创建好之后,开始遍历原数组,将元素按照范围存入每个桶中
for i in range(len(array_list)):
# 确定桶的标号
num = int((array_list[i] - min_v) * (bucket_size - 1 ) / difference_value)
# 使用一个临时变量
temp = bucket_list[num]
temp.append(array_list[i])
# 对每个桶都进行排序
for i in range(len(bucket_list)):
bucket_list[i].sort()
# 排序之后进行输出
res = []
for i in bucket_list:
for j in i:
res.append(j)
return res
after_bucket_sort_list = bucket_sort(array_list)
print(after_bucket_sort_list)
最后结果如下