算法實現之桶排序

      桶排序,網上也稱之爲計數排序,是一種非常簡單、效率很高(空間換時間)的“投機取巧”算法。

先來一個demo:

期末考試完了老師要將同學們的分數按照從高到低排序。小哼的班上只有5個同學,這5個同學分別考了5分、3分、5分、2分和8分,哎考的真是慘不忍睹(滿分是10分)。接下來將分數進行從小到大排序,排序後是2 3 5 5 8。你有沒有什麼好方法編寫一段程序,讓計算機隨機讀入5個數然後將這5個數從小到大輸出?

 

首先我們需要申請一個大小爲11的數組int a[11]。OK現在你已經有了11個變量,編號從a[0]~a[10]。剛開始的時候,我們將a[0]~a[10]都初始化爲0,表示這些分數還都沒有人得過。例如a[0]等於0就表示目前還沒有人得過0分,同理a[1]等於0就表示目前還沒有人得過1分……a[10]等於0就表示目前還沒有人得過10分。

下面開始處理每一個人的分數,第一個人的分數是5分,我們就將相對應a[5]的值在原來的基礎增加1,即將a[5]的值從0改爲1,表示5分出現過了一次。

第二個人的分數是3分,我們就把相對應a[3]的值在原來的基礎上增加1,即將a[3]的值從0改爲1,表示3分出現過了一次。

注意啦!第三個人的分數也是“5分”,所以a[5]的值需要在此基礎上再增加1,即將a[5]的值從1改爲2。表示5分出現過了兩次。

按照剛纔的方法處理第四個和第五個人的分數。最終結果就是下面這個圖啦。

你發現沒有,a[0]~a[10]中的數值其實就是0分到10分每個分數出現的次數。接下來,我們只需要將出現過的分數打印出來就可以了,出現幾次就打印幾次,具體代碼如下:

 

//班上只有5個同學,這5個同學分別考了5分、3分、5分、2分和8分,哎,考得真是慘不忍睹(滿分是10分)
public class Bucket01 {
	public static void main(String ars[]){
		int score[] = {5,3,5,2,8};//實際分數
		int bucket[] = new int[11];//建立"桶"
		for (int i = 0; i < score.length; i++) {
			bucket[score[i]]++;//把分數放到桶裏面
		}
		for (int i = 0; i < bucket.length; i++) {
			while(bucket[i] != 0){//按順序輸出桶中的分數
				System.out.print(i + " ");
				bucket[i]--;
			}
		}
	}
}

舉一反三:

1、輸入0-1000的整數,進行桶排序

代碼如下:

 

//輸入10個0-1000的整數,進行桶排序
public class Bucket02 {
	public static void main(String args[]){
		int num[] = {139,999,20,60,4,80,90,400,684,0};//模擬輸入
		int bucket[] = new int[1001];//建立"桶"
		for (int i = 0; i < num.length; i++) {
			bucket[num[i]]++;
		}
		for (int i = 0; i < bucket.length; i++) {
			while(bucket[i] != 0){
				System.out.print(i + " ");
				bucket[i]--;
			}
		}
	}
	
}


2、輸入0-100的整數,去重並排序

 

代碼如下:

 

//0-100去重並排序
public class Bucket03 {
	public static void main(String ars[]) {
		int num[] = {1,56,24,36,56,42,1,5,6,8};// 模擬目標數組
		int bucket[] = new int[101];//建立"桶"
		for (int i = 0; i < num.length; i++) {
			if (bucket[num[i]] == 0)// 去重,只加一次
				bucket[num[i]]++;
		}
		for (int i = 0; i < bucket.length; i++) {
			if (bucket[i] != 0)//輸出桶內容
				System.out.print(i + " ");
		}
	}
}

 

算法複雜度:代碼中只需兩個for循環,所以算法複雜度爲:O(M+N)。

 

爲什麼說是"投機取巧"的算法?

只記錄了值卻未記錄址。比如現在分別有5個人的名字和分數:huhu 5分、haha 3分、xixi 5分、hengheng 2分和gaoshou 8分。請按照分數從高到低,輸出他們的名字。即應該輸出gaoshou、huhu、xixi、haha、hengheng。所以該算法無法實現。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章