每日演算法 桶排序演算法

2022-08-09 02:18:14 字數 3457 閱讀 5138

桶排序 (bucket sort)或所謂的箱排序,是乙個排序演算法,工作的原理是將陣列分到有限數量的桶子裡。每個桶子再個別排序(有可能再使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排序)。

桶排序是穩定的,且在大多數情況下常見排序裡最快的一種,比快排還要快,缺點是非常耗空間,基本上是最耗空間的一種排序演算法,而且只能在某些情形下使用。

桶排序具體演算法描述如下:

1、設定乙個定量的陣列當作空桶子。

2、尋訪序列,並且把專案乙個乙個放到對應的桶子去。

3、對每個不是空的桶子進行排序。

4、從不是空的桶子裡把專案再放回原來的序列中。

桶排序最好情況下使用線性時間o(n),很顯然桶排序的時間複雜度,取決與對各個桶之間資料進行排序的時間複雜度,因為 其它部分的時間複雜度都為o(n);很顯然,桶劃分的越小,各個桶之間的資料越少,排 序所用的時間也會越少。但相應的空間消耗就會增大。

可以證明,即使選用插入排序作為桶內排序的方法,桶排序的平均時間複雜度為線性。 具體證明,請參考演算法導論。其空間複雜度也為線性。

可以參考中的過程

#include #include #include using namespace  std;  

/*initial arr*/

void initialarr(double *arr,int n)

bucket[flag][j] =temp;

} /* 所有資料重新鏈結 */

int k=0;

for (int i = 0 ; i < 10 ; i++)

} for (int i = 0 ; i<10 ;i++)

delete bucket;

bucket = null;

}

void main()

桶排序是一種很巧妙的排序方法,在處理密集型數排序的時候有比較好的效果(主要是這種情況下空間複雜度不高),其思想也可用在很多演算法題上,詳見後續筆試面試演算法例題。

例題1、一年的全國高考考生人數為500 萬,分數使用標準分,最低100 ,最高900 ,沒有小數,你把這500 萬元素的陣列排個序。

對500w資料排序,如果基於比較的先進排序,平均比較次數為o(5000000*log5000000)≈1.112億。但是我們發現,這些資料都有特殊的條件: 100=建立801(900-100)個桶。將每個考生的分數丟進f(score)=score-100的桶中。這個過程從頭到尾遍歷一遍資料只需要500w次。然後根據桶號大小依次將桶中數值輸出,即可以得到乙個有序的序列。而且可以很容易的得到100分有人,501分有人。

實際上,桶排序對資料的條件有特殊要求,如果上面的分數不是從100-900,而是從0-2億,那麼分配2億個桶顯然是不可能的。所以桶排序有其侷限性,適合元素值集合並不大的情況。

例題2、在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可(記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體)。

分析: 既然要找中位數,很簡單就是排序的想法。那麼基於位元組的桶排序是乙個可行的方法。

思想:將整型的每1byte作為乙個關鍵字,也就是說乙個整形可以拆成4個keys,而且最高位的keys越大,整數越大。如果高位keys相同,則比較次高位的keys。整個比較過程類似於字串的字典序。按以下步驟實施:

1、把10g整數每2g讀入一次記憶體,然後一次遍歷這536,870,912即(102410241024)*2 /4個資料。每個資料用位運算">>"取出最高8位(31-24)。這8bits(0-255)最多表示255個桶,那麼可以根據8bit的值來確定丟入第幾個桶。最後把每個桶寫入乙個磁碟檔案中,同時在記憶體中統計每個桶內資料的數量,自然這個數量只需要255個整形空間即可。

2、繼續以記憶體中的整數的次高8bit進行桶排序(23-16)。過程和第一步相同,也是255個桶。

3、一直下去,直到最低位元組(7-0bit)的桶排序結束。我相信這個時候完全可以在記憶體中使用一次快排就可以了。

例題3、給定n個實數x1,x2,...,xn,求這n個實數在實軸上相鄰2個數之間的最大差值m,要求設計線性的時間演算法

典型的最大間隙問題。

要求線性時間演算法。需要使用桶排序。桶排序的平均時間**度是o(n).如果桶排序的資料分布不均勻,假設都分配到同乙個桶中,最壞情況下的時間複雜度將變為o(n^2).

桶排序: 最關鍵的建桶,如果桶設計得不好的話桶排序是幾乎沒有作用的。通常情況下,上下界有兩種取法,第一種是取乙個10n或者是2n的數,方便實現。另一種是取數列的最大值和最小值然後均分作桶。

對於這個題,最關鍵的一步是:由抽屜原理知:最大差值m>= (max(v[n])-min(v[n]))/(n-1)!所以,假如以(max(v[n])-min(v[n]))/(n-1)為桶寬的話,答案一定不是屬於同乙個桶的兩元素之差。因此,這樣建桶,每次只保留桶裡面的最大值和最小值即可。

**如下:

//距離平均值為offset = (arraymax - arraymin) / (n - 1), 則距離最大的數必然大於這個值  

#include #define maxsize 100 //實數的個數

#define maxnum 32767

using namespace std;

struct barrel

; int barreloperation(double* array, int n)

double offset = (arraymax - arraymin) / (n - 1); //所有數的平均間隔

//對桶進行初始化

for(i = 0; i < n; i++)

//對資料進行分桶

for(i = 0; i < n; i++) else

} for(i = 0; i <= n; i++)

int maxoffset = 0.0;

for(i = 0; i < nbarrel - 1; i++)

return maxoffset;

} int main()

; //所需處理的資料

int n = 8; //數的個數

//double array[maxsize] = ;

//int n = 3;

int maxoffset = barreloperation(array, n);

cout << maxoffset << endl;

return 0;

}

桶排序演算法

桶排序 bucket sort 或所謂的箱排序,是乙個排序演算法,工作的原理是將陣列分到有限數量的桶子裡。每個桶子再個別排序 有可能再使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排序 桶排序是鴿巢排序的一種歸納結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間 n 但桶排序並不...

演算法 桶排序

參考 個人理解 需求不同,實現方式也不同,但原理是一樣 能符合要求,簡單快速實現的方式才是最好的實現方式.網上找到了能反映桶原理的例子 define maxlength 10 int main int argc,const char argv int bucket maxlength for int...

桶排序演算法

桶排序 bucket sort 或所謂的箱排序,是乙個排序演算法,工作的原理是將陣列分到有限數量的桶子裡。每個桶子再個別排序 有可能再使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排序 桶排序是鴿巢排序的一種歸納結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間 n 但桶排序並不...