資料結構排序系列詳解之九 桶排序

2021-06-17 23:06:40 字數 2225 閱讀 1662

基本思想:

假定輸入是由乙個隨機過程產生的[0, m)區間上均勻分布的實數。將區間[0, m)劃分為n個大小相等的子區間(桶),將n個輸入元素分配到這些桶中,對桶中元素進行排序,然後依次連線桶輸入0 ≤a[1..n]

[桶——關鍵字]對映函式

bindex=f(key)   其中,bindex 為桶陣列b的下標(即第bindex個桶), k為待排序列的關鍵字。桶排序之所以能夠高效,其關鍵在於這個對映函式,它必須做到:如果關鍵字k1很顯然,對映函式的確定與資料本身的特點有很大的關係,我們下面舉個例子:

假如待排序列k= 。這些資料全部在1—100之間。因此我們定製10個桶,然後確定對映函式f(k)=k/10。則第乙個關鍵字49將定位到第4個桶中(49/10=4)。依次將所有關鍵字全部堆入桶中,並在每個非空的桶中進行快速排序後得到如下圖所示:

對上圖只要順序輸出每個b[i]中的資料就可以得到有序序列了。

演算法核心**如下:

/// /// 桶排序

///

///如果有重複的數字,則需要 list陣列,這裡舉的例子沒有重複的數字

///

/// 待排陣列

/// 待排陣列中的最大數,如果可以提供的話

///

static int bucket_sort(int unsorted, int maxnumber = 97)

return sorted;

}static void main(string args)

;var sorted = bucket_sort(x, 97);

for (int i = 0; i < sorted.length; i++)

console.readline();

}

桶排序代價分析桶排序利用函式的對映關係,減少了幾乎所有的比較工作。實際上,桶排序的f(k)值的計算,其作用就相當於快排中劃分,已經把大量資料分割成了基本有序的資料塊(桶)。然後只需要對桶中的少量資料做先進的比較排序即可。

對n個關鍵字進行桶排序的時間複雜度分為兩個部分:

(1) 迴圈計算每個關鍵字的桶對映函式,這個時間複雜度是o(n)。

(2) 利用先進的比較排序演算法對每個桶內的所有資料進行排序,其時間複雜度為  ∑ o(ni*logni) 。其中ni 為第i個桶的資料量。

很顯然,第(2)部分是桶排序效能好壞的決定因素。儘量減少桶內資料的數量是提高效率的唯一辦法(因為基於比較排序的最好平均時間複雜度只能達到o(n*logn)了)。因此,我們需要盡量做到下面兩點:

(1) 對映函式f(k)能夠將n個資料平均的分配到m個桶中,這樣每個桶就有[n/m]個資料量。

(2) 盡量的增大桶的數量。極限情況下每個桶只能得到乙個資料,這樣就完全避開了桶內資料的「比較」排序操作。當然,做到這一點很不容易,資料量巨大的情況下,f(k)函式會使得桶集合的數量巨大,空間浪費嚴重。這就是乙個時間代價和空間代價的權衡問題了。

對於n個待排資料,m個桶,平均每個桶[n/m]個資料的桶排序平均時間複雜度為:

o(n)+o(m*(n/m)*log(n/m))=o(n+n*(logn-logm))=o(n+n*logn-n*logm)

當n=m時,即極限情況下每個桶只有乙個資料時。桶排序的最好效率能夠達到o(n)。

總結:桶排序的平均時間複雜度為線性的o(n+c),其中c=n*(logn-logm)。如果相對於同樣的n,桶數量m越大,其效率越高,最好的時間複雜度達到o(n)。

當然桶排序的空間複雜度

為o(n+m),如果輸入資料非常龐大,而桶的數量也非常多,則空間代價無疑是昂貴的。此外,桶排序是穩定的。

即以下三點:

1,桶排序是穩定的

2,桶排序是常見排序裡最快的一種,比快排還要快…大多數情況下

3,桶排序非常快,但是同時也非常耗空間,基本上是最耗空間的一種排序演算法

補充:在查詢演算法中,基於比較的查詢演算法最好的時間複雜度也是o(logn)。比如折半查詢、平衡二叉樹、紅黑樹等。但是hash表卻有o(c)線性級別的查詢效率(不衝突情況下查詢效率達到o(1))。那麼:hash表的思想和桶排序是不是有一曲同工之妙呢?

實際上,桶排序對資料的條件有特殊要求,如果陣列很大的話,那麼分配幾億個桶顯然是不可能的。

所以桶排序有其侷限性,適合元素值集合並不大的情況。

資料結構與演算法 十個排序演算法之九 桶排序

桶排序是計數排序的公升級版。它利用了函式的對映關係,高效與否的關鍵就在於這個對映函式的確定。為了使桶排序更加高效,我們需要做到這兩點 在額外空間充足的情況下,盡量增大桶的數量 使用的對映函式能夠將輸入的 n 個資料均勻的分配到 k 個桶中 同時,對於桶中元素的排序,選擇何種比較排序演算法對於效能的影...

常用資料結構之桶式排序

關於桶式排序,其實以前見到過,當成了乙個排序技巧來記了。具體就是,有乙個序列,有n個數,並且每個數取值範圍是0 100。問如何快速的進行排序。那麼我們可以很容易想到,就是在開乙個大小為一百的陣列,並且初始化為0,然後遍歷所給的序列,比如遍歷到了23,就把23放入新開陣列下標為23的位置上,具體表現在...

資料結構之桶排序(python實現)

coding utf 8 每乙個桶代表乙個區間範圍,裡面可以承載乙個或多個元素 1.建立桶,並確定每乙個桶的區間範圍 2.遍歷原始數列,把元素對號入座放入各個桶中 3.對每個桶內部的元素分別進行排序 4.遍歷所有的桶,輸出所有元素 def buckersort string 1.得到數列的最大值 m...