桶排序 (Bucket Sort) 又稱箱排序,是鴿巢排序的一種歸納結果(有關鴿巢排序的內容留待後補)。
桶排序是比較特殊的排序,它不屬於比較排序,即有序的建立不是基於元素的比較與交換而消除逆序得到的,比較形象的講,其對有序的建立是基於桶數組在物理內存上本身的連續性和有序性,將其作爲索引,然後建立該索引與待排序數組的映射關係,然後通過遍歷索引而傾倒出待排序元素,則傾倒的過程自然遵循桶數組的物理內存連續性而得到有序的結果。基於這一分析,桶排序不受到 O(nlogn) 的下限影響。
其工作的過程是先建立有限個數量的桶,每個桶內可以使用別的排序。然後將元素投入對應的桶中,對每個子桶進行排序。完成以後依次將子桶中的元素倒出到原始數組,得到結果。
比較特殊的情況是建立的桶的數量與待排序數組中的最大元素減去最小元素再加一的個數相同,這樣的話可以實現一對一的映射,也免去了對子桶的排序。舉例來說,如果原數組中有元素3,則 Bucket[3]++; 這樣還有一個附加的好處是,重複的元素只要對應的桶再加一即可,在傾倒的時候,只要桶不爲空則繼續傾倒,也很好實現。下面的java代碼給出的正是這種桶排序的實現。
java代碼實現 (該實現中默認已知輸入的最小值是0,實際上這是不太恰當的,比較好的做法是對最大最小值都尋找,然後分配桶空間):
//This algorithm is limited and impractical because there exists a pre-assumption
//for the input. In this case the minimum input cannot be negative and the maximum
//input should be reachable.
public class BucketSort{
public static void BucketSort(Integer[] a){
//Find the max
int max=a[0];
for(int i=0;i<a.length;i++)
if(a[i]>max) max=a[i];
// System.out.println("max="+max);
//Fill the bucket;
int[] Bucket=new int[max+1];
for(int i=0;i<a.length;i++){
Bucket[a[i]]++;
}
/* System.out.println("Bucket status:");
for(int i=0;i<Bucket.length;i++) System.out.print(Bucket[i]+" ");
System.out.println();
*/
//Dump back into the array from the bucket;
int j=0;
for(int i=0;i<=max;i++){
while(Bucket[i]!=0){
a[j]=i;
Bucket[i]--;
j++;
}
}
}
public static void main(String[] args){
System.out.println("Bucket Sort:");
Integer[] elements={3,4,1,8,10,2,0,6,5};
System.out.print("Original elements: ");
for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" ");
System.out.println();
BucketSort(elements);
System.out.print("After sorting: ");
for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" ");
System.out.println();
}
}
平均時間複雜度:O(n+k).
附圖一張,圖中的情況是每個桶是作爲一個數據範圍的索引,與代碼實現的不太一樣: