桶排序講解及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;