//為了讓大家更容易了解 Bubble sort 演算法,
//    我把 bbsort.c 用更白話文方式解釋
//    用註解方式插入到 bbsortSort( ) 函數內 
// 注意喔, 原先在 e3.nctu 給大家的 bbsort.c 有個小 BUG 喔 !!
// 少做一個 pass  (就是 for i 少做一次! ) 
// 請看程式裡面的面註解說明 !  
// 通常測試不出來有Bug,  Why why WHY??? 


//bbsort.c  -- by tsaiwn@csie.nctu.edu.tw
// 氣泡排列法, 類似教官要把一列學生由低到高排好
// 或當過兵的:  班長要把一列班兵由低到高排好! (由小到大)
// 也可以說類似水中的氣泡一直往上冒
/// 所以, 才稱為 Bubble sort (氣泡排列法)
/// 注意, 若沒使用 FLAG 提早結束則一般稱為鄰近比較交換法
/// 鄰近比較交換法: Sibling compare and exchange sort
/// 
/////
/// 想一想, 這樣最多會比較(compare)幾次呢?
//  Pass 1:  n-1 個比較
//  Pass 2:  n-2 個比較
// ..
//  Pass n-1:  n-(n-1) = 1 個比較
//
/// So,  n-1 + (n-2) + ... +2 + 1 =  (n-1+1)*(n-1)/2
///  梯形面積 = (上底 + 下底) * 高 /2 =  n*(n-1)/2
///    == (n*n - n) /2
///  當 n 很大, 則 n 比 n*n 小很多可忽略不算 = n*n /2
/////  顯然 n*n /2 與 n 的平方成正比
///// 所以你會聽到 :
//////  Bubble sort 的 time complexity 是 Big O of n平方
//////   寫做 O(n*n)
///////////////////////////
 
 
void bubbleSort(int x[ ], int n) { //氣泡排列法 Bubble sort
  // Bubble sort method, sort n records in array int x[ ];
  //要排序的資料在 array x[0], x[1], ... x[n-1]
  int i, k, flag;  // flag 用來指出是否已經排好, 是就不必再做了!
  int tmp;   // 用來對調 (switch) 時的臨時變數 
  for(i = 1; i <= n-1; i++) {    // 做 n-1 趟 (pass)! 原來程式有 BUG!
            // 我放在 e3.nctu 的 bbsort.c 是寫 i < n -1  有 Bug!
            // 這樣會少做一趟, 但大部分不會有事 (與 data 有關)
            // 因通常不必做到最後一趟(pass; 回合)就已經排序好了 :-)
       // pass1 第 1 趟, pass 2 第二趟,... pass n-1 (最多這樣)
       // 例如 3 個資料則最多要走兩趟 ( 兩個 pass, 兩個回合)
     flag = 0; // assume already sorted; 0 = 這趟沒有鄰近的對調 
     for(k = 0; k < n-i; k++) {  // i = 1 時, 比到 x[n-2] : x[n-1]
          // 每趟都要從頭(k=0)比起, 每趟第一次都是 x[0] : x[1]
          // 每趟都只要走到 k = n-i-1 就可, 做 x[k] : x[k+1]
          // 因每走一趟(pass), 右邊就會多一個已經排好的!
          // 當然要寫成做到最後 ;k < n-2 ; 也可, 是白做的而已!
        if(x[k] > x[k+1]) {  // 左邊比較大就對調; x[k] < x[k+1]
             // 左大右小就來做對調, 這樣就會 Ascending 遞增排序 !
             // 鄰近兩個相比, 注意這Loop最後一次是 k = n-i-1
             // 當 i == 1 (第一趟), 最後一次就是 k = n-1-1 = n-2
             /// 最後一趟是 i = n-1 那趟!
             // 當 i == n-1, 最後一次就是 k = n-(n-1)-1 = 0
          tmp = x[k+1]; x[k+1] = x[k]; x[k] = tmp; // swap
          flag = 1;   // 有對調, 不知道是否排好了 ! 做記號!
        } // if
     }// for k  
     // 走完一趟, 若是都沒有對調(flag是0), 那表示再重新走也沒用!
     if(flag == 0) break; // already sorted! done !
  } // for i; 注意 flag == 0 表示這趟沒有發生對調的事 ! 
}// bubbleSort(