第二篇關於排序的 依然是交換類的排序 --冒泡排序 (相鄰比序法)
數據結構的時候學過 現在比較喜歡寫博客 雖然簡單基礎 但是還是寫於此
冒泡排序基本思想就是 :反覆掃描待排序的數組 ,在掃描的過程中順次比較相鄰的兩個元素的大小,若逆序則交換位置
上代碼:
/**
* 標誌性的兩層循環 第二層循環是確定排序的數組範圍 ,所以第一層循環每一輪都是將第二層確定的範圍中最大的數移到最後
*
* 第一層循環次數是 length-1 第二層循環次數是 length-1-i
*
* @author laowang
*/
public class Test {
private static int[] data;
/**
* 冒泡排序 未 精簡版 此時比較次數仍然是n*(n-1)/2,所以時間複雜度仍是O(n^2),失敗的算法
*/
public static void Sort_Bad() {
int temp; // 堅決不能定義在for循環內部 ,會加大空間複雜度
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9 - i; j++) {
if (data[j] > data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
/**
* 改進版冒泡排序 可以算法在最佳情況的時間複雜度降到:O(n)
*/
public static void Sort_Better() {
int temp;
boolean isSorted = false; // 此變量表示數組是否已經有序 ,這就是對最優情況的優化 ,當數組已經有序時
// ,不需要繼續進行循環
for (int i = 0; i < 9 && !isSorted; i++) { // 如果一輪第二層循環結束都沒有進行過交換
// 說明數組已經有序,所以一旦isSorted ==
// true 排序結束
isSorted = true; // 第一層循環每次都需將它賦值爲false
for (int j = 0; j < 9 - i; j++) {
if (data[j] > data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
isSorted = false;
}
}
}
}
/**
*
* 用增強for循環輸出當前數組
*/
public static void PrintData() {
for (int i : data) {
System.out.print(" " + i);
}
System.out.println("");
}
public static void main(String[] args) {
data = new int[10];
System.out.println("輸入十個數 進行冒泡排序");
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 10; i++) {
data[i] = scanner.nextInt();
}
// Sort_Bad();
Sort_Better();
PrintData();
scanner.close();
}
}
冒泡排序空間複雜度爲:O(1),平均時間複雜度爲:O(n^2)
冒泡排序算法最壞情況是:待排序數組是完全逆序的,此時第i趟冒泡排序共需進行n-i次比較,3(n-i)次移動,經過n-1趟排序後
* 總的比較次數是:n*(n-1)/2,移動次數是:3*n*(n-1)/2;所以時間複雜度爲O(n^2),
最好的情況是數組完全有序,所以沒有交換數組元素這個過程。 但是我上面寫了兩個版本,當然第一個版本是普通的,時間複雜度是O(n^2);
第二個版本是進行了優化:在循環過程中,如果數組已經有序,則循環結束, 時間複雜度爲O(n)。
冒泡到此結束,下節是直接插入排序,(我最近怎麼這麼想寫算法呢 ,看來是幡然悔悟了~~~~)