"""
桶排序
桶排序的原理是将数组分到有限数量的桶中,
再对每个桶子再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),
最后将各个桶中的数据有序的合并起来。
时间复杂度:
桶排序在输入N个数据有M个桶时,如果每个桶的数据接近N/M个且桶内使用基于比较的排序,
则桶排序的时间复杂度为O(N+M*N/M*log(N/M)).如果N=M时,每个桶只有一个数据,
时间复杂度降低为O(N).
桶排序的时间复杂度为O(N+M),桶排序是稳定的排序
"""
import random
class bucketSort(object):
"""桶"""
def __init__(self, bucket_len=None):
self.bucket_len = bucket_len # 桶长
if bucket_len:
self.bucket_list = [None for old in range(bucket_len)] # 桶列表
def _max(self, oldlist): # 取list最大值
_max = oldlist[0]
for old in oldlist:
if old > _max:
_max = old
return _max
def _min(self, oldlist): # 取list最小值
_min = oldlist[0]
for old in oldlist:
if old < _min:
_min = old
return _min
def sort(self, oldlist):
_max = self._max(oldlist) # 取最大值
_min = self._min(oldlist) # 取最小值
scope = _max - _min # 要排序list的value 范围
if self.bucket_len is None:
self.bucket_len = len(oldlist) # 桶长
self.bucket_list = [None for old in range(self.bucket_len)] # 桶列表
k = self.bucket_len/(scope+1) # 系数 该放入的桶序号 = 值*k 原公式 桶序号 = (值*桶范围)/值范围 实际使用的时候取整,可能会大了一点,这里分母+1
print("k", k)
print('scope', scope)
print('bucket_len', self.bucket_len)
print('bucket_list', self.bucket_list)
print('oldlist', oldlist)
for old in oldlist:
index = int((old-_min)*k) # 应该放入哪个桶中。。 减去最小值才能得出相对位置的值
# print('value:', old, 'index:', index)
if self.bucket_list[index] is None: # 如果桶中为空,直接赋值
self.bucket_list[index] = old
elif isinstance(self.bucket_list[index], (int, float)): # 如果桶中有值,创建有序list
item = self.bucket_list[index]
if old < item:
self.bucket_list[index] = [old, item]
else:
self.bucket_list[index] = [item, old]
elif isinstance(self.bucket_list[index], list): # 如果桶中为list,插入排序
insert_index = None
insert_value = None
for cur, value in enumerate(self.bucket_list[index]):
# print('enum', cur, value)
if old < value:
insert_index, insert_value = cur, old
continue
if insert_index is None:
self.bucket_list[index].append(old)
else:
self.bucket_list[index].insert(insert_index, insert_value)
print('bucket_list', self.bucket_list)
cur = 0
# 填入原list
for bucket in self.bucket_list:
if isinstance(bucket, list):
for ii in bucket:
oldlist[cur] = ii
cur += 1
elif isinstance(bucket, int):
oldlist[cur] = bucket
cur += 1
def __call__(self, oldlist):
self.sort(oldlist)
return oldlist
if __name__=='__main__':
a = [random.randint(0, 100) for old in range(10)]
# a = [51, 86, 79, 5, 21, 14, 11, 94, 3, 31]
sort = bucketSort(5) # 参数是几个桶 ,不传的话后面会自己计算list的长度作为同
sort(a)
print(a)
觉得有帮助可以打点小费。。。。