對冒泡排序法的個人理解
下文全部以數組的從小到大排序為例,對象排序、從大到小排序同理。
冒泡排序法,是從數組的第一個數開始,依次向後比較相鄰的兩個數;前者比較大時,就將二者換位,這樣一次遍歷完成後,最大的數就在最後;之後再從第一個數開始向後比較(不比較最後一個數),依此類推。
選擇排序法,是用數組的第一個數,依次和後面的數比較;後面的數小於第一個數時,將其置換到第一位,這樣一次遍歷完成後,第一個數就是最小的數;之後再從第二個數開始和後面比較,依此類推。
以前寫冒泡排序法時,都是寫完兩個循環之後,用第一次外循環和最後一次外循環時比較的數組角標,來計算兩個循環的初始值和條件表達式。今天覺得每次都要算一下這個好麻煩,然後想了想外循環和內循環的意義:
1 for(i = 0; i < N-1; i++) {//內循環進行次數:數組長度-1 2 //內循環:一次冒泡,循環完成後數組最後一個數是最大的數 3 for(j = 0; j < N-i-1; j++) {//比較進行次數:數組長度-已完成排序數量-1(已完成排序數量=內循環已完成次數=i) 4 if(buf[j] > buf[j+1]) { 5 temp = buf[j]; 6 buf[j] = buf[j+1]; 7 buf[j+1] = temp; 8 }9 } 10 }
每次內循環完成後,數組最後一個數就是最大的數,因此一共需要進行(數組長度-1)次內循環,所以外循環的條件表達式為 i<N-1 ;
每次內循環中,需要比較的次數為剩余需要排序的數量-1次(最後一個數不需要和後面的數比較);又因剩余需要排序的數量=數組長度-已完成排序的數量,而已完成排序的數量=內循環完成次數,所以每次內循環需要進行(數組長度-內循環已完成次數-1)次比較,所以內循環的條件表達式為 j<N-i-1 。
這樣理解就簡單多了。
同時,也可以據此計算出一次冒泡排序法需要比較的次數:N(N-1)/2次。(N-i-1(i從0到N-2)的累加和)。
總結一下:
對於外循環,我們只關心內循環需要進行的次數,也就是把最大的數放到最後這個操作重復的次數(N-1次),因此外循環為 for(i = 0; i < N-1; i++) ;
對於內循環,我們只關心每次內循環比較的次數,也就是每次把最大的數放到最後需要比較的次數(N-i-1次),因此內循環為 for(j = 0; j < N-i-1; j++) ;
至於是從小到大排序,還是從大到小排序,這些事情就交給比較環節去改變就可以了。
同樣的,對於選擇排序法,有:
外循環需要從第一個數向後遍歷,直到倒數第二個數,因此一共需要進行(數組長度-1)次內循環,所以外循環的條件表達式為 i<N-1 ,外循環為 for(i = 0; i < N-1; i++) ;
每次內循環中,已完成排序數量為i,而每次內循環都是從當前還沒完成排序的第一個數,向後遍歷到數組結尾,因此內循環為 for(j = i; j < N-1; j++) 。
同時,也可以據此計算出一次選擇排序法需要比較的次數:N(N-1)/2次。(N-i-1(i從0到N-2)的累加和)。
對冒泡排序法的個人理解