1. 程式人生 > >常用排序演算法:桶排序

常用排序演算法:桶排序

演算法思路:

我們之前提到過計數排序,計數排序在某些情況下並不太適合,例如元素範圍太大的情況,桶排序算是對於計數排序的一種改進,桶排序首先根據元素大小放置到不同的桶中,然後在對每一個桶內元素進行排序。

例如陣列[29,25,3,49,9,37,21,43],可以以10為區間來存放元素,具體操作如下圖:

關於“桶”這個結構怎麼實現,在python裡面可以用二位陣列來表示[ [  ], [   ], [  ] ....],總得來說桶排序步驟:
            1 . 建桶
            2.  元素存放到桶裡面
            3.  桶內元素進行排序(第二步和第三步可以合併到一起,因為初始的桶為空是有序的,每次只需執行一次插入即可保持有序
            4.  依次取出每個桶內元素

時間複雜度:平均O(n+k), 最壞O(n^2 * k)都放到一個桶裡面了

空間複雜度:O(nk)

程式碼實現:

def bucket_sort(nums, buckets):
    """
    桶排序
    :param nums: 無序陣列
    :param buckets: 桶個數
    :return: 有序陣列
    """
    bucket = [[] for x in range(buckets)]  # 建立空桶
    num = max(nums) - min(nums) + 1
    l = num // buckets + 1 if num % buckets else num // buckets   # 計算每個桶大小
    for i in nums:
        bucket_num = i // l # 計算元素應該放入到哪一個桶裡面
        bucket[bucket_num].append(i)
        # 維護桶內元素有序。
        # 因為之前的桶內是有序的,插入一個新的元素可以使用插入排序繼續保持桶內有序
        tmp = i
        j = len(bucket[bucket_num]) - 2
        while j >= 0 and bucket[bucket_num][j] > tmp:  # 執行插入操作
            bucket[bucket_num][j + 1] = bucket[bucket_num][j]
            j -= 1
        bucket[bucket_num][j+1] = tmp
    res = []
    # 依次取出桶內元素
    for i in bucket:
        res.extend(i)
    return res