桶排序與基數排序

2021-06-26 04:32:20 字數 2371 閱讀 8755

桶排序的基本思想

假設有一組長度為n的待排關鍵字序列k[1....n]。首先將這個序列劃分成m個的子區間(桶) 。然後基於某種對映函式 ,將待排序列的關鍵字k對映到第i個桶中(即桶陣列b的下標 i) ,那麼該關鍵字k就作為b[i]中的元素(每個桶b[i]都是一組大小為n/m的序列)。接著對每個桶b[i]中的所有元素進行比較排序(可以使用快排)。然後依次列舉輸出b[0]....b[m]中的全部內容即是乙個有序序列。

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

桶排序代價分析

桶排序利用函式的對映關係,減少了幾乎所有的比較工作。實際上,桶排序的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),如果輸入資料非常龐大,而桶的數量也非常多,則空間代價無疑是昂貴的。此外,桶排序是穩定的。

基數排序

上面的問題是多關鍵字的排序,但單關鍵字也仍然可以使用這種方式。

比如字串「abcd」 「aesc」 "dwsc" "rews"就可以把每個字元看成乙個關鍵字。另外還有整數 425、321、235、432也可以每個位上的數字為乙個關鍵字。

基數排序的思想就是將待排資料中的每組關鍵字依次進行桶分配。比如下面的待排序列:

278、109、063、930、589、184、505、269、008、083

我們將每個數值的個位,十位,百位分成三個關鍵字: 278 -> k1(個位)=8  ,k2(十位)=7 ,k3=(百位)=2。

然後從最低位個位開始(從最次關鍵字開始),對所有資料的k1關鍵字進行桶分配(因為,每個數字都是 0-9的,因此桶大小為10),再依次輸出桶中的資料得到下面的序列。

930、063、083、184、505、278、008、109、589、269

再對上面的序列接著進行針對k2的桶分配,輸出序列為:

505、008、109、930、063、269、278、083、184、589

最後針對k3的桶分配,輸出序列為:

008、063、083、109、184、269、278、505、589、930

效能分析

很明顯,基數排序的效能比桶排序要略差。每一次關鍵字的桶分配都需要o(n)的時間複雜度,而且分配之後得到新的關鍵字序列又需要o(n)的時間複雜度。假如待排資料可以分為d個關鍵字,則基數排序的時間複雜度將是o(d*2n) ,當然d要遠遠小於n,因此基本上還是線性級別的。基數排序的空間複雜度為o(n+m),其中m為桶的數量。一般來說n>>m,因此額外空間需要大概n個左右。

但是,對比桶排序,基數排序每次需要的桶的數量並不多。而且基數排序幾乎不需要任何「比較」操作,而桶排序在桶相對較少的情況下,桶內多個資料必須進行基於比較操作的排序。因此,在實際應用中,基數排序的應用範圍更加廣泛。

桶排序與基數排序

思想 要排序的資料的範圍為小於m的正整數。這樣,使用乙個大小為m的bucket陣列,陣列初始化為0。bucket陣列的每個單元稱為 桶 然後依次掃瞄待排序資料 a1,a2,a3,a4,ai 讀到ai的時候,bucket ai 增加1。這樣,待排序資料讀完後,掃瞄陣列bucket,列印出排序表即可。v...

基數排序(桶排序)

1。什麼是基數排序 radix sort 基數排序 屬於分配式排序 distribution sort 又稱 桶排序 bucket sort 它是通過鍵值的各個位的值,將要排序的元素分配至某些 桶 中,達到排序的作用。2.它和歸併一樣,屬於穩定型演算法。public void radixsort i...

基數排序(桶排序)

思想 先把這組資料的個位排有序,再把十位排有序,再排百位 千位 include include include include void showarr int arr,int len printf n int getmaxnumfin int arr,int len 找陣列中最大數,並求出最大數的...