一. 基本思想
通過從左到右不斷交換逆序的相鄰元素,在一輪的交換之後,可以讓未排序的元素上浮到右側。在一輪循環中,如果沒有發生交換,就說明數組已經是有序的,此時可以直接退出。
二. 代碼實現
- 版本一
/**
- <br>冒泡排序</br>
*/
public class BubbleSort {
/**
* 外層循環控制比較的輪數,內層循環進行依次相鄰元素的比較
* 在第一輪比較中,最大的元素冒泡到了最後的位置;
* 在第二輪比較中,第二大的元素冒泡到了倒數第二個位置;
* 依此類推。
* @param arr
*/
public static void sort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
private static void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
- 版本二
/**
* <br>冒泡排序</br>
*/
public class BubbleSort2 {
public static void sort(int[] arr) {
int n = arr.length;
boolean swap;
do {
/**
* 這裏的swap主要考慮的 如果數組是近乎有序的,
* 那麼在某輪比較後,沒有產生swap操作,即剩下的
* 未排序的元素已經是有序的了,就不用再比較了。
*/
swap = false;
for (int i = 0; i < n - 1; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr, i, i + 1);
swap = true;
}
}
/**
* 每一趟Bubble Sort都將最大的元素放在了最後的位置
* 所以下一次排序, 最後的元素可以不再考慮
*/
n--;
} while (swap);
}
private static void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
/**
* <br>冒泡排序優化</br>
*/
public class BubbleSort3 {
/**
* 按照之前升序排列,每輪循環將剩下元素中最大的元素調到最後.
* 考慮這樣的情況:假設在前面未排序的元素中,後面靠近尾端的元素已經是有序的了,
* 但是之前的做法還是會每次把這些元素包括進去遍歷.
* 例如:原始一組數據: 3,6,2,4,5
* 第一輪排序後:3,2,4,5,6
* 按照之前的思想:接下來的一輪迴會在剩下的未排序序列 3,2,4,5中找出最大的元素調到最後,
* 但是4,5本身是有序的,他們在上一輪的遍歷中並沒有交換位置,所以我們完全可以依據上一輪的遍歷設置個記錄
* 最後交換順序的指針,然後只需要遍歷這個指針之前的元素.
*
* @param arr
*/
public static void sort(int[] arr) {
int n = arr.length;
int lastSwapIndex;
do {
//重置,清零
lastSwapIndex = 0;
for (int i = 0; i < n - 1; i++) {
if (arr[i] > arr[i+1]){
swap(arr,i,i+1);
// 記錄最後一次的交換位置,在此之後的元素在下一輪掃描中均不考慮,注意這裏的臨界點
lastSwapIndex = i+1;
}
}
n = lastSwapIndex;
} while (lastSwapIndex > 0);
}
private static void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}