前言
桶排序(Bucket sort)或所謂的箱排序,是一個排序算法,工作的原理是將數組分到有限數量的桶里。每個桶再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序),最后依次把各個桶中的記錄列出來記得到有序序列。桶排序是鴿巢排序的一種歸納結果。當要被排序的數組內的數值是均勻分配的時候,桶排序使用線性時間(Θ(n))。但桶排序並不是比較排序,他不受到O(n log n)下限的影響。
基本思想
桶排序的思想近乎徹底的分治思想。
桶排序假設待排序的一組數均勻獨立的分布在一個范圍中,並將這一范圍划分成幾個子范圍(桶)。
然后基於某種映射函數f ,將待排序列的關鍵字 k 映射到第i個桶中 (即桶數組B 的下標i) ,那么該關鍵字k 就作為 B[i]中的元素 (每個桶B[i]都是一組大小為N/M 的序列 )。
接着將各個桶中的數據有序的合並起來 : 對每個桶B[i] 中的所有元素進行比較排序 (可以使用快排)。然后依次枚舉輸出 B[0]….B[M] 中的全部內容即是一個有序序列。
補充: 映射函數一般是 f = array[i] / k; k^2 = n; n是所有元素個數
為了使桶排序更加高效,我們需要做到這兩點:
在額外空間充足的情況下,盡量增大桶的數量
使用的映射函數能夠將輸入的 N 個數據均勻的分配到 K 個桶中
同時,對於桶中元素的排序,選擇何種比較排序算法對於性能的影響至關重要。
實現邏輯
設置一個定量的數組當作空桶子。
尋訪序列,並且把項目一個一個放到對應的桶子去。
對每個不是空的桶子進行排序。
從不是空的桶子里把項目再放回原來的序列中。
演示
分步驟圖示說明:設有數組 array = [63, 157, 189, 51, 101, 47, 141, 121, 157, 156, 194, 117, 98, 139, 67, 133, 181, 13, 28, 109],對其進行桶排序:

算法代碼
這里主要是為了方便表達桶排序的思想,使用了vector,在單個桶中還用了stl的sort
1 //桶排序 2 void BucketSort(int *arr, int n) 3 { 4 int max = arr[0]; 5 for (int i = 1; i < n; i++) 6 { 7 if (arr[i] > max) 8 max = arr[i]; 9 } 10 vector<int> *bucket = new vector<int>[max / 10 + 1]; 11 for (int i = 0; i < n; i++) 12 { 13 int change = arr[i] / 10; //元素arr[i]所在的桶編號 14 bucket[change].push_back(arr[i]); 15 } 16 for (int i = 0; i < n; i++) 17 { 18 if (bucket[i].size() > 0) 19 { 20 sort(bucket[i].begin(), bucket[i].end()); //桶內排序 21 } 22 } 23 int index = 0; 24 for (int i = 0; i < n; i++) //桶遍歷 25 { 26 for (int j = 0; j < bucket[i].size(); j++) //遍歷桶內元素 27 { 28 arr[index++] = bucket[i][j]; 29 } 30 } 31 }
算法分析
- 平均時間復雜度:O(n + k)
- 最佳時間復雜度:O(n + k)
- 最差時間復雜度:O(n ^ 2)
- 空間復雜度:O(n * k)
- 穩定性:穩定
桶排序最好情況下使用線性時間O(n),桶排序的時間復雜度,取決與對各個桶之間數據進行排序的時間復雜度,因為其它部分的時間復雜度都為O(n)。很顯然,桶划分的越小,各個桶之間的數據越少,排序所用的時間也會越少。但相應的空間消耗就會增大。
[參考:https://blog.csdn.net/developer1024/article/details/79770240]