1. 程式人生 > >桶排序講解及python3實現

桶排序講解及python3實現

#!/usr/bin/env python
# coding:utf-8

def bucketSort(nums):
    # 選擇一個最大的數
    max_num = max(nums)
    # 建立一個元素全是0的列表, 當做桶
    bucket = [0]*(max_num+1)
    # 把所有元素放入桶中, 即把對應元素個數加一
    for i in nums:
        bucket[i] += 1

    # 儲存排序好的元素
    sort_nums = []
    # 取出桶中的元素
    for j in range(len(bucket)):
        if bucket[j] != 0:
            for y in range(bucket[j]):
                sort_nums.append(j)

    return sort_nums

nums = [5,6,3,2,1,65,2,0,8,0]
print bucketSort(nums)

"""
[0, 0, 1, 2, 2, 3, 5, 6, 8, 65]
"""

上述使用的桶的數字容量均為1。

桶排序(bucket sort)假設輸入資料服從均勻分佈。平均情況下他的時間代價是O(n)。計數排序假設輸入資料分佈於一個小區間的整數,而桶排序則假設輸入是一個隨機過程產生的,該過程將元素均勻獨立地分佈於[0,1)區間上。 1.桶排序的基本思想 桶排序將[0,1)區間劃分為n個相同的大小的子區間,這些子區間被稱為桶。然後將n個輸入元素分別放入各自的桶中。因為輸入時均勻獨立的,所以一般不會有很多數同時落在一個桶中的情況。這樣,我們想對各個桶中的資料進行排序,然後遍歷每個桶,按照次序把各個桶中的元素列出來即可。 一個桶排序的示例如圖:

桶排序示例

簡單來說就是把陣列 arr 劃分為n個大小相同子區間(桶),每個子區間各自排序,最後合併。這樣說是不是和分治法有點像了 啊!因為分治法就是分解 —— 解決 ——合併這樣的套路。我認為這樣想沒毛病。可以理解為桶排序是一種特殊的分治法,特殊的地方主要體現在前兩部分(這樣說不知道對不對~)。具體來說如下: 分解部分,採用了計數排序類似的思想,通過分解,雖然沒有比較,但是將資料基本按照大小劃分了幾個區間。針對輸入資料均勻分佈的特點,因此將資料分佈的區間可以均勻分為n個子區間。那麼就有

max - min = n * width; (1)

其中,max,min 是輸入資料的最大值最小值,n是子區間個數,width是子區間寬度。 這樣劃分後,每個資料x對應的桶的編號(0-n-1)就是;

index = (x - min) / width = (x - min) / (max - min) * n;(2)

這樣,當我們取n=Array.length時,相應的每個資料的存放的桶的編號也就確定了:

index = (x - min) / (max - min) * Array.length

如果我們取n= (max-min)/Array.length 時,就有:

index = (x - min) / (max - min) * (max-min) / Array.length = (x - min) / Array.length;