資料結構(python) —— 【18排序: 桶排序】

BecauseLoveUEveryday發表於2020-09-27

桶排序

上一博文講了計數排序,那麼在計數排序中,如果元素的範圍比較大(比如在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)

結果為:

[0, 1, 1, 1, 1, 2, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 12, 12, 13, 15, 19, 22, 24, 25, 25, 26, 28, 28, 29, 29, 29, 30, 31, 35, 36, 37, 38, 41, 42, 42, 43, 45, 46, 51, 54, 54, 55, 57, 57, 58, 59, 60, 62, 63, 63, 66, 67, 69, 69, 69, 70, 70, 72, 75, 76, 77, 77, 79, 80, 82, 83, 84, 84, 87, 87, 89, 89, 90, 91, 91, 92, 92, 93, 93, 94, 94, 100, 100, 100, 100, 102, 104, 108, 108, 108, 108, 109, 110, 111, 113, 114, 115, 117, 119, 119, 120, 120, 121, 121, 124, 124, 125, 126, 127, 127, 128, 128, 128, 131.......]

相關文章