在不影響seo的情況下!網站跳轉【搜尋引擎跳轉】
阿新 • • 發佈:2020-10-13
基本介紹
氣泡排序的基本思想是:通過對待排序序列從前向後(從下標較小的元素開始),依次比較相鄰的元素,若發現逆序則交換,使值較大的元素逐漸從前移向後部,就想水底下的氣泡一樣逐漸向上冒.
優化:
因為在排序過程中個元素不斷接近自己正確的位置,如果一趟比較下來沒有進行過交換,就說明序列有序,因此要在排序過程中設定一個flag判斷元素是否進行過交換.從而減少不必要的比較.
圖解
- 一共進行了arr.length - 1次迴圈
- 每一趟排序的次數在逐漸減少
- 如果發現在某趟排序中,沒有發生一次交換,可以提前介紹氣泡排序.
程式碼實現
直觀,分趟實現
public class BubbleSort { public static void main(String[] args) { int[] arr = {3, 9, -1, 10, 20}; System.out.println("原始資料:"); System.out.println(Arrays.toString(arr)); //第一趟 int temp = 0; // 用於交換的輔助變數 for (int j = 0; j < arr.length - 1; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } System.out.println("第一趟排序後的結果:"); System.out.println(Arrays.toString(arr)); //第二趟 for (int j = 0; j < arr.length - 1 - 1; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } System.out.println("第二趟排序後的結果:"); System.out.println(Arrays.toString(arr)); //第三趟 for (int j = 0; j < arr.length - 1 - 2; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } System.out.println("第三趟排序後的結果:"); System.out.println(Arrays.toString(arr)); //第四趟 for (int j = 0; j < arr.length - 1 - 3; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } System.out.println("第四趟排序後的結果:"); System.out.println(Arrays.toString(arr)); } }
原始資料:
[3, 9, -1, 10, 20]
第一趟排序後的結果:
[3, -1, 9, 10, 20]
第二趟排序後的結果:
[-1, 3, 9, 10, 20]
第三趟排序後的結果:
[-1, 3, 9, 10, 20]
第四趟排序後的結果:
[-1, 3, 9, 10, 20]
上面的程式碼,就是按照圖解分析,分趟來完成的,直觀顯示了氣泡排序的原理,但是,如果陣列非常大,那肯定是不能這樣手動分趟完成的,觀察上面的程式碼,我們發現一個規律,每趟修改的程式碼也就是for迴圈的第二個條件,而且還非常有規律,所以修改後的程式碼如下:
雙重迴圈完成
public class BubbleSort { public static void main(String[] args) { int[] arr = {3, 9, -1, 10, 20}; System.out.println("原始資料:"); System.out.println(Arrays.toString(arr)); bubbleSort(arr); } private static void bubbleSort(int[] arr) { int temp = 0;//用於交換的輔助變數 for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j+1]){ temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } System.out.printf("第%d次排序後的結果為:\n",i+1); System.out.println(Arrays.toString(arr)); } } }
原始資料:
[3, 9, -1, 10, 20]
第1次排序後的結果為:
[3, -1, 9, 10, 20]
第2次排序後的結果為:
[-1, 3, 9, 10, 20]
第3次排序後的結果為:
[-1, 3, 9, 10, 20]
第4次排序後的結果為:
[-1, 3, 9, 10, 20]
但是,我們發現第3和4次排序的結果和第二次的一樣,也就是說我們進行了一些不必要的排序
優化程式碼
因為在排序過程中個元素不斷接近自己正確的位置,如果一趟比較下來沒有進行過交換,就說明序列有序,因此要在排序過程中設定一個flag判斷元素是否進行過交換.從而減少不必要的比較.
public class BubbleSort { public static void main(String[] args) { int[] arr = {3, 9, -1, 10, 20}; System.out.println("原始資料:"); System.out.println(Arrays.toString(arr)); bubbleSort(arr); } private static void bubbleSort(int[] arr) { boolean flag = false; // 用於判斷程式碼一趟是否進行過交換,沒有則表示已經排好序了,可以提前結束程式了 int temp = 0;//用於交換的輔助變數 for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j+1]){ flag = true; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } if (!flag){ break; }else { flag = false; //這裡還需要把flag設定為false,因為進入else的結果中,flag是true } System.out.printf("第%d次排序後的結果為:\n",i+1); System.out.println(Arrays.toString(arr)); } } }
原始資料:
[3, 9, -1, 10, 20]
第1次排序後的結果為:
[3, -1, 9, 10, 20]
第2次排序後的結果為:
[-1, 3, 9, 10, 20]
因為進行了雙重for迴圈,所以時間複雜度為 \(O(N^2)\)