簡單排序算法實現——桶排序

桶排序 (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();
	}
}


還應該說明的是,桶排序的另一個特殊性在於對於輸入數據做了預先的假設,因此也有別於一般的排序算法對任意輸入數據的普適性。該假設在於:所有輸入數據分佈比較均勻且集中,沒有出現極端的數據。在滿足該條件的情況下,桶排序非常高效適用,且易於編程,可以將百萬級的數據量在毫秒級的時間範圍內處理完。 但是一旦該數據分佈均勻集中的假設不滿足,其空間效率將極低。舉例來說,如果待排序數據爲:-10000, 0 , 2 ,1 , 3, 20000. 在這種情況下,將創建幾萬個桶空間而並不使用,這顯然是不合適的。


平均時間複雜度:O(n+k).


附圖一張,圖中的情況是每個桶是作爲一個數據範圍的索引,與代碼實現的不太一樣:



發佈了30 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章