天天看点

数据结构(python) —— 【18排序: 桶排序】

桶排序

上一博文讲了计数排序,那么在计数排序中,如果元素的范围比较大(比如在1到1亿之间),如何改造算法?

桶排序(Bucket Sort): 首先将元素分在不同的桶中,再对每个桶中的元素排序

桶排序的表现取决于数据的分布,也就是需要对不同的数据排序时采取不同的分桶策略

平均情况复杂度: O(n+k)

最坏情况时间复杂度: O(k * n^2)

空间复杂度: O(nk)

桶排序原理很简单,比如一个列表中元素最大值是max=100000,按照计数排序,我们需要一个100000大小的列表,但是如果使用桶排序,则我们可以将0-1000放一个桶里,然后这个桶内每次放入一个元素就进行一次冒泡排序即将桶内也排好序;将1001-2000也放一个桶…这样最大值为100000的列表只需要放入100个桶中就行了。

代码:

'''
TOP: 桶排序
author: Blue
time: 2020-08-08
QQ: 2458682080
'''

def bucket_sort(li, n=100, max_num=10000):
    buckets = [[] for _ in range(n)]  # 创建桶——建立n个空一维列表的二维列表
    for var in li:
        i = min(var // (max_num // n), n - 1)   # i表示var这个数放到几号桶里
        # max_num // n 表示每个桶有几个数
        # 用min是为了防止比如10000这个数出现,按道理应该放到第100个桶,但我们只有0-99号桶,所以取较小值,让10000放进99号桶
        buckets[i].append(var)  # 把var放进桶里
        for j in range(len(buckets[i])-1, 0, -1):  # 放入桶后,用该桶最后一个数往前进行冒泡排序
            if buckets[i][j] < buckets[i][j-1]:
                buckets[i][j], buckets[i][j-1] = buckets[i][j-1], buckets[i][j]
            else:
                break
    sorted_li = []
    for buc in buckets:
        sorted_li.extend(buc)
    return sorted_li

import random
li = [random.randint(0, 10000) for i in range(10000)]
li = bucket_sort(li)
print(li)
           

结果为: