氣泡排序:
氣泡排序就像水裡的氣泡一樣,輕的氣泡會一點一點地浮到水面。在這個演算法中,我們將待排序的元素比喻成氣泡,透過比較相鄰元素的值,讓較大的元素慢慢“浮”到陣列的末端。
具體步驟如下:
- 比較相鄰的兩個元素,如果前一個比後一個大(假設我們要從小到大排序),就交換它們的位置。
- 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。
- 針對所有的元素重複以上的步驟,除了最後已經排序好的元素。
- 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
public static void bubbleSort(int[] arr) {
int n = arr.length;
boolean swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交換 arr[j] 和 arr[j + 1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// 如果內層迴圈沒有發生交換,說明陣列已經有序,可以提前結束排序
if (!swapped) {
break;
}
}
}
快速排序:
快速排序的思想是找一個基準值(pivot),將陣列分為兩部分,左邊都比基準值小,右邊都比基準值大。然後對這兩部分再遞迴地進行同樣的操作。
具體步驟如下:
- 選擇一個基準值,通常是陣列的中部或最後一個元素。
- 將陣列分為兩部分,小於基準值的元素放到左邊,大於基準值的元素放到右邊。
- 對左右兩個子陣列重複步驟1和2,直到每個子陣列的元素數量不超過1。
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// 找到基準元素的正確位置
//之前:{2, 9, 3, 6, 4, 1, 8, 7, 5}
int pivotIndex = partition(arr, low, high);
//之後:{2, 3, 4, 1, →5←, 6, 8, 7, 9} 5號歸位
// 對基準左邊和右邊的子陣列進行快速排序
quickSort(arr, low, pivotIndex - 1);//排序 {2, 3, 4, 1}
quickSort(arr, pivotIndex + 1, high);//排序 {6, 8, 7, 9}
}
}
private static int partition(int[] arr, int low, int high) {
// 選擇最後一個元素作為基準
int pivot = arr[high];
int i = low;
for (int j = low; j < high; j++) {
// 將小於基準的元素放到左邊
if (arr[j] < pivot) {
swap(arr, i++, j);
}
}
// 將基準放到正確的位置
swap(arr, i, high);
return i;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
歸併排序:
歸併排序是採用分治法的一個非常典型的應用。它的思想是將陣列分成若干個小陣列,對每個小陣列進行排序,然後將小陣列合併成較大的陣列,直到最後只有一個排序完成的大陣列。
具體步驟如下:
- 把陣列分成若干個小陣列,直到每個小陣列只有一個元素。
- 將相鄰的小陣列合併成較大的陣列,合併時對陣列進行排序。
- 重複步驟2,直到最後只有一個排序完成的大陣列。
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int mid = arr.length / 2;
int[] left = new int[mid];
int[] right = new int[arr.length - mid];
System.arraycopy(arr, 0, left, 0, mid);
System.arraycopy(arr, mid, right, 0, arr.length - mid);
mergeSort(left);
mergeSort(right);
merge(arr, left, right);
}
private static void merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, k = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
總結:
這三種排序演算法各有特點,氣泡排序簡單但效率較低,快速排序效率高但需要額外的儲存空間,歸併排序則是效率和穩定性都比較好的排序演算法。在實際應用中,根據不同的需求選擇合適的排序演算法是很重要的。