元素分配到桶中
对桶中元素排序
**桶排序（Bucket sort）**或所謂的**箱排序**，是一個排序演算法，工作的原理是將陣列分到有限數量的桶裡。每個桶再個別排序（有可能再使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排序）。桶排序是鴿巢排序的一種歸納結果。當要被排序的陣列內的數值是均勻分配的時候，桶排序使用線性時間（{\displaystyle \Theta (n)}）。

桶排序以下列程序進行：

1. 設置一個定量的陣列當作空桶子。
2. 尋訪序列，並且把項目一個一個放到對應的桶子去。
3. 對每個不是空的桶子進行排序。
4. 從不是空的桶子裡把項目再放回原來的序列中。

伪代码
---

```
**function** bucket-sort(array, n) **is**
  buckets ← new array of n empty lists
  **for** i = 0 **to** (length(array)-1) **do**
    insert *array[i]* into buckets[msbits(array[i], k)]
  **for** i = 0 **to** n - 1 **do**
    next-sort(buckets[i])
  **return** the concatenation of buckets[0], ... buckets[n-1]
```

C++实现算法
-------

假设数据分布在[0，100)之间，每个桶内部用链表表示，在数据入桶的同时插入排序。然后把各个桶中的数据合并。

```
#include<iterator>
#include<iostream>
#include<vector>
using namespace std;
const int BUCKET\_NUM = 10;

struct ListNode{
 explicit ListNode(int i=0):mData(i),mNext(NULL){}
 ListNode\* mNext;
 int mData;
};

ListNode\* insert(ListNode\* head,int val){
 ListNode dummyNode;
 ListNode \*newNode = new ListNode(val);
 ListNode \*pre,\*curr;
 dummyNode.mNext = head;
 pre = &dummyNode;
 curr = head;
 while(NULL!=curr && curr->mData<=val){
 pre = curr;
 curr = curr->mNext;
 }
 newNode->mNext = curr;
 pre->mNext = newNode;
 return dummyNode.mNext;
}

ListNode\* Merge(ListNode \*head1,ListNode \*head2){
 ListNode dummyNode;
 ListNode \*dummy = &dummyNode;
 while(NULL!=head1 && NULL!=head2){
 if(head1->mData <= head2->mData){
 dummy->mNext = head1;
 head1 = head1->mNext;
 }else{
 dummy->mNext = head2;
 head2 = head2->mNext;
 }
 dummy = dummy->mNext;
 }
 if(NULL!=head1) dummy->mNext = head1;
 if(NULL!=head2) dummy->mNext = head2;
 
 return dummyNode.mNext;
}

void BucketSort(int n,int arr[]){
 vector<ListNode\*> buckets(BUCKET\_NUM,(ListNode\*)(0));
 for(int i=0;i<n;++i){
 int index = arr[i]/BUCKET\_NUM;
 ListNode \*head = buckets.at(index);
 buckets.at(index) = insert(head,arr[i]);
 }
 ListNode \*head = buckets.at(0);
 for(int i=1;i<BUCKET\_NUM;++i){
 head = Merge(head,buckets.at(i));
 }
 for(int i=0;i<n;++i){
 arr[i] = head->mData;
 head = head->mNext;
 }
}

```

Java實現算法
--------

```
 private int indexFor(int a, int min, int step) {
 return (a - min) / step;
 }

 public void bucketSort(int[] arr) {

 int max = arr[0], min = arr[0];
 for (int a : arr) {
 if (max < a)
 max = a;
 if (min > a)
 min = a;
 }
 // 該值也可根據實際情況選擇
 int bucketNum = max / 10 - min / 10 + 1;
 List buckList = new ArrayList<List<Integer>>();
 // create bucket
 for (int i = 1; i <= bucketNum; i++) {
 buckList.add(new ArrayList<Integer>());
 }
 // push into the bucket
 for (int i = 0; i < arr.length; i++) {
 int index = indexFor(arr[i], min, 10);
 ((ArrayList<Integer>) buckList.get(index)).add(arr[i]);
 }
 ArrayList<Integer> bucket = null;
 int index = 0;
 for (int i = 0; i < bucketNum; i++) {
 bucket = (ArrayList<Integer>) buckList.get(i);
 insertSort(bucket);
 for (int k : bucket) {
 arr[index++] = k;
 }
 }

 }

 // 把桶內元素插入排序
 private void insertSort(List<Integer> bucket) {
 for (int i = 1; i < bucket.size(); i++) {
 int temp = bucket.get(i);
 int j = i - 1;
 for (; j >= 0 && bucket.get(j) > temp; j--) {
 bucket.set(j + 1, bucket.get(j));
 }
 bucket.set(j + 1, temp);
 }
 }

```

JavaScript实现算法
--------------

```
Array.prototype.bucketSort = function(num) {
  function swap(arr, i, j) {
    const temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
  }
  const max = Math.max(...this)
  const min = Math.min(...this)
  const buckets = []
  const bucketsSize = Math.floor((max - min) / num) + 1
  for(let i = 0; i < this.length; i++) {
    const index = ~~(this[i] / bucketsSize)
    !buckets[index] && (buckets[index] = [])
    buckets[index].push(this[i])
    let l = buckets[index].length
    while(l > 0) {
      buckets[index][l] < buckets[index][l - 1] && swap(buckets[index], l, l - 1)
      l--
    }
  }
  let wrapBuckets = []
  for(let i = 0; i < buckets.length; i++) {
    buckets[i] && (wrapBuckets = wrapBuckets.concat(buckets[i]))
  }
  return wrapBuckets
}
const arr = [11, 9, 6, 8, 1, 3, 5, 1, 1, 0, 100]
console.log(arr.bucketSort(10))
```

JavaScript实现递归算法
----------------

```
Array.prototype.bucketSort = function()
{
  var start = 0;
  var size = this.length;
  var min = this[0];
  var max = this[0]; 
  for (var i = 1; i < size; i++){
    if (this[i] < min){min = this[i];}
    else{ if(this[i] > max){max = this[i];} }
  }
  if (min != max){
    var bucket = new Array(size);
    for (var i = 0; i < size; i++){bucket[i] = new Array();}
    var interpolation = 0;
    for (var i = 0; i < size; i++){
      interpolation = Math.floor(((this[i] - min) / (max - min)) * (size - 1));
      bucket[interpolation].push(this[i]);
    }
    for (var i = 0; i < size; i++){
      if (bucket[i].length > 1){bucket[i].bucketSort();}//遞歸
      for(var j = 0; j < bucket[i].length; j++){this[start++] = bucket[i][j];}
    }
  }
};
```

Python 3.10 實現演算法
-----------------

```
def is\_sort(arr: list) -> bool:
    for i in range(len(arr) - 1):
        if arr[i] > arr[i + 1]:
            return False
    return True

def bucket\_sort(arr: list, is\_sub\_bucket: bool = False):
    if is\_sort(arr):
        return

    bucket\_num: int = max(arr) // 10 + 1 if not is\_sub\_bucket else 10
    buckets: list[list] = [[] for \_ in range(bucket\_num)]

    for a in arr:
        i: int = a // 10 if not is\_sub\_bucket else a % 10
        buckets[i].append(a)
    
    arr.clear()
    for bucket in buckets:
        bucket\_sort(bucket, is\_sub\_bucket=True)
        arr += bucket

if \_\_name\_\_ == '\_\_main\_\_':
    arr = [29, 25, 3, 49, 9, 37, 21, 43]
    bucket\_sort(arr)
    print(arr)

```

外部链接
----

* Bucket Sort in C++
* Bucket Sort & PHP Sample[永久]

參考
--

* Thomas H. Cormen，Charles E. Leiserson，Ronald L. Rivest，and Clifford Stein。*Introduction to Algorithms*, Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Section 8.4: Bucket sort, pp.174–177.
* Paul E. Black "Postman's Sort" （页面存档备份，存于） from Dictionary of Algorithms and Data Structures at NIST。
* Robert Ramey *The Postman's Sort* （页面存档备份，存于） *C Users Journal* Aug. 1992

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
排序算法 |
| --- |
|  |
| 理论 | 
* 計算複雜性理論
* 大O符号
* 全序关系
* 数据结构术语列表
* 原地算法
* 稳定性
* 比较排序
* 自适应排序（英语：）
* 排序网络（英语：）
* 整数排序（英语：）
* X+Y排序（英语：）
* 量子排序（英语：）

 |
|  |
| 交换排序 | 
* 冒泡排序
* 鸡尾酒排序
* 奇偶排序
* 梳排序
* 侏儒排序
* 快速排序
* 慢速排序
* 臭皮匠排序
* Bogo排序

 |
|  |
| 选择排序 | 
* 选择排序
* 堆排序
* 平滑排序（英语：）
* 笛卡尔树排序（英语：）
* 锦标赛排序（英语：）
* 圈排序（英语：）
* 弱堆排序（英语：）

 |
|  |
| 插入排序 | 
* 插入排序
* 希尔排序
* 伸展排序
* 二叉查找树排序
* 图书馆排序
* 耐心排序

 |
|  |
| 归并排序 | 
* 归并排序
* 梯级归并排序（英语：）
* 振荡归并排序（英语：）
* 多相归并排序（英语：）

 |
|  |
| 分布排序 | 
* 美国旗帜排序（英语：）
* 珠排序
* 桶排序
* 爆炸排序（英语：）
* 计数排序
* 比較計數排序
* 插值排序
* 鸽巢排序
* 相邻图排序（英语：）
* 基数排序
* 闪电排序（英语：）

 |
|  |
| 并发排序 | 
* 双调排序器（英语：）
* Batcher归并网络
* 两两排序网络（英语：）

 |
|  |
| 混合排序 | 
* 塊排序（英语：）
* Tim排序
* 内省排序
* Spread排序（英语：）
* 归并插入排序（英语：）

 |
|  |
| 其他 | 
* 拓撲排序
* 煎餅排序
* 意粉排序（英语：）

 |

 |