對於一個無序列,我們想要將它轉換成有序列,所謂的有序列為升序(由小到大)或者降序(由大到小),要完成這樣的排序,有很多種排序算法,下面介紹其中一種:冒泡排序。
冒泡排序的原理為:以升序為例,將相鄰的兩個元素進行比較,如果前面一個元素比后面一個元素大,則兩者進行進行交換。后面的以此類推,下面進行圖解。
比如現在有一個數組為:int[] num = {6,5,9,1,2,4};現在要將這個數組中的元素排列為升序排列:1,2,4,5,6,9
根據冒泡排序的原理:數組中的元素用相鄰(下標相鄰)的兩個元素進行比較,如果前面比后面的值大,則交換:
第一趟排序:6,5,9,1,2,4
第一次比較:6和5比較,前面6比后面5大,則兩者交換,交換后結果為:5,6,9,1,2,4 (每次得到的結果用於下一次比較)
第二次比較:6和9比較,前面6比后面9小,則兩者不交換,結果為:5,6,9,1,2,4
第三次比較:9和1比較,前面9比后面1大,則兩者交換,交換后結果為:5,6,1,9,2,4
第四次比較:9和2比較,前面9比后面2大,則兩者交換,交換后結果為:5,6,1,2,9,4
第五次比較:9和4比較,前面9比后面4大,則兩者交換,交換后結果為:5,6,1,2,4,9
以上是第一趟排序,數組一共有6個元素,相鄰的兩個比較,一共比較了5次,當一趟排序完成之后,最大值9已經在最后面了,那么下次比較將不用再做比較了。
第二趟排序:5,6,1,2,4,9
第一次比較:5和6比較,前面5比后面6小,則兩者不交換,結果為:5,6,1,2,4,9
第二次比較:6和1比較,前面6比后面1大,則兩者交換,結果為:5,1,6,2,4,9
第三次比較:6和2比較,前面6比后面2大,則兩者交換,結果為:5,1,2,6,4,9
第四次比較:6和4比較,前面6比后面4大,則兩者交換,結果為5,1,2,4,6,9
第三趟排序:5,1,2,4,6,9
第一次比較:5和1比較,前面5比后面1大,則兩者交換,交換后結果為:1,5,2,4,6,9
第二次比較:5和2比較,前面5比后面2大,則兩者交換,交換后結果為:1,2,5,4,6,9
第三次比較:5和4比較,前面5比后面4大,則兩者交換,交換后結果為:1,2,4,5,6,9
第四趟排序:1,2,4,5,6,9 (可能有人會認為,這里已經得到正確的排序了,后面就不需要再排序了,不能這么理解,因為我們數組的值不一定每次都是這幾個數字,因此還是需要繼續比較完)
第一次比較:1和2比較,前面1比后面2小,則兩者不交換,結果為:1,2,4,5,6,9
第二次比較:2和4比較,前面2比后面4小,則兩者不交換,結果為:1,2,4,5,6,9
第五趟排序:1,2,4,5,6,9
第一次比較:1和2比較,前面1比后面2小,則兩者比較換,結果為:1,2,4,5,6,9
以上就是對數組中的元素進行比較分析,下面是圖示:
通過文字說明和圖示說明,我們可以很輕松的寫出每一趟相鄰兩個數比較的代碼:
1 for(int i =0;i < num.length-1;i++){ 2 //實現相鄰的兩個數進行比較 3 if(num[i] > num[i+1]){ 4 //前面比后面的數大,則兩者進行交換 5 int temp = num[i]; 6 num[i] = num[i+1]; 7 num[i+1] = num[i]; 8 } 9 }
執行完上面的代碼后,代表的是一趟排序,可以完成一趟以內,相鄰的兩個數進行比較,也就是說要完成冒泡排序,只要將上面的代碼執行5次就可以了,
但是還是有問題,單從代碼上面閱讀來看,循環完以上代碼,一定會比較5次,但是實際上,根據圖示可以很清楚的看出來,每多一趟排序,則少比較一次。
那么一下才是完整的冒泡排序:
1 public void bubble(){ 2 //定義一個數組: 3 int[] num = {6,5,9,1,2,4}; 4 //使用循環:外層循環表示需要排序多少趟,num.length-1=5,保證進行5次排序 5 for(int i = 0;i < num.length-1;i++){ 6 //使用循環,完成每一趟排序中的所有比較,注意:每多比較一趟,則少比較一次 7 for(int j = 0;j < num.length-1-i;j++){ 8 //兩個相鄰的兩個數進行比較: 9 if(num[j] > num[j+1]){ 10 //前面的數比后面的數大,則交換 11 int temp = num[j]; 12 num[j] = num[j+1]; 13 num[j+1] = temp; 14 } 15 } 16 } 17 }
注意:閱讀以下上面的代碼
第一個for循環:i < num.length-1;目的是為了讓實現排序的趟數比數組長度少1,比如上面6個元素的數組,只需要排序5次
第二個for循環:表示每一趟排序中,相鄰兩個數的比較,j < num.length-1-i;這個減少i是什么意思呢減i是為了實現,每多一趟排序,則相鄰的兩個數比較次數減少一次,而i又是從0開始的。
如果還不明白,閱讀以下代碼流程:
第一趟排序:
當i = 0 則num.length-1-i = 5 很容易得出第二個循環會循環5次,也就是說會有5組相鄰的兩個數進行比較
當i = 1,則num.length-1-i = 4 則第二個for循環會循環4次,也就是說會有4組相鄰的兩個數進行比較
當i = 2 則num.length-1-i = 3 則第二個for循環會循環3次,也就是說會有3組相鄰的兩個數進行比較
當i = 3 則num.length-1-i = 2 則第二個for循環會循環2次,也就是說會有3組相鄰的兩個數進行比較
當i = 4 則num.length-1-i = 1 則第二個for循環會循環1尺,也就是說會有3組相鄰的兩個數進行比較
所以:第一個for循環是控制我們需要排序多少趟,而第二個for循環是控制我們在每一趟中需要多少次相鄰兩個數進行比較。
以上為冒泡排序。加油!