背景:冒泡算法是一個十分基礎的算法,奈何自己腦子不好使,總也記不住,故做此文章,以便記憶。
理解:冒泡算法的官方說明就不寫了,通俗的理解就是每一輪進行--相鄰兩兩比較--並把---最大的那個數----找出來放在最後;因爲每一輪循環都會得到一個最大的數冒出來,所以稱之爲冒泡算法;
寫代碼前有兩點要理解:
1. 整個數組完成排序需要進行n-1輪比較:例如
int a[] = {5, 3, 9, 6, 2};
長度爲5 (a.length = 5)的數組a,每一輪比較會得出一個最大值,
那麼完成所有排序,就需要進行n-1(數組a來說,就需比較4次)輪比較,
因爲最後一個數沒必要在比較了;
2 . 每一輪找到最大的數,需要進行n-1次比較:
int a[] = {5, 3, 9, 6, 2};
如果長度爲5,一輪循環比較中需要比較4次,就可得到最大值了;
因爲這個數跟自己是不需要比較的;
代碼實現與理解:(理論不夠,代碼來湊)網上有多種寫法,最初不知道哪一種是正確的,
其實原理理解了,寫法就不重要了,反正都叫冒泡排序
1. 初級實現:
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = 0; i < a.length - 1; i++) {
// 最外層控制多少輪循環(此處爲a.length - 1,就是4次循環)
for (int j = 0; j < a.length - 1; j++) {
// 裏層控制多少次比較(此處爲a.length - 1,就是4次循環,不做優化的)
if (a[j] > a[j+1]){
// 如果前一個數比後一個數大,則進行數據交換
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割線=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
2. 對於內層查找最大數的循環次數進行優化,因爲每一次都會找到一個最大值,
所以後續的比較就不用跟最大值比較了;所以內層循環的次數是遞減的,第一輪是4次;
第二輪是3次...
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = 0; i < a.length - 1; i++) {
// 最外層控制多少輪循環(此處爲a.length - 1,就是4次循環)
for (int j = 0; j < a.length - 1 - i; j++) {
/**
* 裏層控制多少次比較,此處爲a.length - 1 - i ,
* 就是4,3,2,1次循環,依次遞減的;
* 因爲每次循環都找到一個最大值,所以接下來的循環就不用和找出的最大值進行比較了
* 第1次i=0, 裏面循環4次;第2次i=1, 裏面循環3次就可以;
* 第3次i=2, 裏面循環2次;第4次i=3, 裏面循環1次就可以;
* 至此,執行完畢
*/
if (a[j] > a[j+1]){
// 如果前一個數比後一個數大,則進行數據交換
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割線=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
3. 原理同2,只不過實現方式不一樣,算的上是2上的另一種寫法
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = a.length - 1; i > 0; i--) {
/**
* 最外層控制多少輪循環(此處爲a.length - 1,就是4次循環)
* 此時i=4, i=3, i =2, i =1依次遞減
*/
for (int j = 0; j < i; j++) {
/**
* 裏層控制多少次比較,此處爲 i ,
* 就是4,3,2,1次循環,依次遞減的;
* 因爲每次循環都找到一個最大值,所以接下來的循環就不用和找出的最大值進行比較了
* 第1次i=4, 裏面循環4次;第2次i=3, 裏面循環3次就可以;
* 第3次i=2, 裏面循環2次;第4次i=1, 裏面循環1次就可以;
* 至此,執行完畢
*/
if (a[j] > a[j+1]){
// 如果前一個數比後一個數大,則進行數據交換
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割線=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
總結: 以前固執的認爲冒泡排序僅僅是一種寫法,對於多種不同的寫法存在疑惑;其實算法就是理解,理解了,至於實現方式,只要用到了冒泡的原理,那麼都可以說成是冒泡算法