1、基本介紹
冒泡排序(Bubble Sorting)的基本思想是:
通過對待排序序列從前向後(從下標較小的元素開始),依次比較相鄰元素的值,若發現逆序則交換,使值較大的元素逐漸從前移向後部,就象水底下的氣泡一樣逐漸向上冒。
因爲排序的過程中,各元素不斷接近自己的位置,如果一趟比較下來沒有進行過交換,就說明序列有序,因此要在排序過程中設置
一個標誌flag判斷元素是否進行過交換。從而減少不必要的比較。(這裏說的優化,可以在冒泡排序寫好後,在進行)
2、演示冒泡過程的例子
假設原始數組:3, 9, -1, 10, 20
第一趟排序
(1) 3, 9, -1, 10, 20 // 如果相鄰的元素逆序就交換
(2) 3, -1, 9, 10, 20
(3) 3, -1, 9, 10, 20
(4) 3, -1, 9, 10, 20
第二趟排序
(1) -1, 3, 9, 10, 20 //繼續從第一、二個數開始比較,逆序就交換順序
(2) -1, 3, 9, 10, 20
(3) -1, 3, 9, 10, 20
第三趟排序
(1) -1, 3, 9, 10, 20
(2) -1, 3, 9, 10, 20
第四趟排序
(1) -1, 3, 9, 10, 20
小結冒泡排序規則:
(1) 一共進行 數組的大小-1 次大的循環
(2) 每一趟排序的次數在逐漸的減少
(3) 如果我們發現在某趟排序中,沒有發生一次交換, 可以提前結束冒泡排序。(這個就是優化點)
動圖演示:
3、代碼實現
按照我 演示冒泡排序的例子,寫出相對應的代碼:
public class BubbleSort {
public static void main(String[] args) {
int arr[] = { 3, 9, -1, 10, 20 };
// 第一趟排序,就是將第一大的數排在倒數第一位
for (int j = 0; j < arr.length - 1 - 0; 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));
}
}
將重複代碼合併,並優化代碼:
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);
System.out.println("排序後");
System.out.println(Arrays.toString(arr));
}
// 根據前面的排序規律,將冒泡排序封裝成一個方法
public static void bubbleSort(int[] arr) {
// 冒泡排序 的時間複雜度 O(n^2)
int temp = 0;// 臨時變量
boolean flag = false;// 標識變量,表示是否進行過交換
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!!!, 進行下次判斷
}
}
}
}