資料結構與演算法--蠻力法之氣泡排序與時間複雜度分析(java)
蠻力法
蠻力法又稱窮舉法和列舉法,是一種簡單直接地解決問題的方法,常常直接基於問題的描述,所以蠻力法也是最容易應用的方法。但是蠻力法所設計的演算法時間特性往往是比較低的,典型的指數時間演算法一般都是通過蠻力搜尋得到的。所謂的指數時間演算法,是指輸入資料的數量依線性成長,所花的時間將會以指數成長。
應用
常用的蠻力法應用演算法有我們比較熟悉的氣泡排序、選擇排序。
氣泡排序
比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一步,最後的元素應該會是最大的數。
針對所有的元素重複以上的步驟,除了最後一個。
持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
當然,你也可以從大到小排序,也可以從後向前冒泡。其特徵操作是相鄰元素的比較和交換。
實現步驟
接下來,實現氣泡排序,基於將最大的值排到最後。初始程式碼如下:
/** * @Author: AndyLin * @Title: bubbleSort * @Description: 氣泡排序 * @param: array */ public static void bubbleSort(int[] array){ for(int i = array.length-1; i > 0; i--){ for(int j = 0; j < i; j++){ if(array[j] > array[j+1]){ int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } }
時間複雜度分析
若陣列初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M,均達到最小值:
Cmin = n-1,Mmin = 0,即得出最理想的狀態,時間複雜度為O(n) 。
若陣列初始狀態是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值:
Cmax = n(n-1)/2,Mmax = 3n(n-1)/2,計算複雜度的原則,去掉常數,去掉最高項係數,即最壞的情況,時間複雜度為O(n^2)。
效能改進
當外層迴圈第一次完成後,排序便完成了,然後後面的迴圈只有比較,而沒有資料交換。當一次外層迴圈中,相鄰的元素沒有發生資料交換,即說明陣列已經是有序的了,這時可以跳出迴圈。
/**
* @Author: AndyLin
* @Title: bubbleSort
* @Description: 氣泡排序
* @param: array
*/
public static void bubbleSort(int[] array){
for(int i = array.length-1; i > 0; i--){
boolean flag = true;
for(int j = 0; j < i; j++){
if(array[j] > array[j+1]){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = false;//標記資料交換
}
}
if(flag){
break;//對於一個已經有序的陣列,演算法完成第一次外層迴圈後就會返回
}
}
}