選擇排序是最直觀的排序演算法:每輪從未排序區域選出最小元素,放到已排序區域末尾。
i 為已排序邊界i 到末尾區間尋找最小元素索引i 交換i 達到倒數第二個元素package com.robert.paixu;
public class SortAlgorithm {
public static void main(String[] args) {
int[] numbers = {1, 9, 2, 4, 3, 7, 8, 6, 0, 12, 10, 11, 20, -20, 190, 120, -50, 130};
selectSort(numbers);
display(numbers);
}
private static void selectSort(int[] arrays) {
for (int i = 0; i < arrays.length - 1; i++) {
int indexSmallest = getIndexOfSmallest(arrays, i);
if (arrays[indexSmallest] < arrays[i]) {
swap(arrays, i, indexSmallest);
}
}
}
private static int getIndexOfSmallest(int[] arrays, int start) {
int smallFlag = start + 1;
for (int j = start + 1; j < arrays.length; j++) {
if (arrays[smallFlag] > arrays[j]) // 修正:應為 >
smallFlag = j;
}
return smallFlag;
}
private static void swap(int[] arrays, int i, int j) {
int temp = arrays[i];
arrays[i] = arrays[j];
arrays[j] = temp;
}
private static void display(int[] arrays) {
for (int val : arrays)
System.out.print(val + " ");
}
}
-50 -20 0 1 2 3 4 6 7 8 9 10 11 12 20 120 130 190
| 情況 | 時間複雜度 | 說明 |
|---|---|---|
| 最佳 | O(n²) | 即使有序仍需完整掃描 |
| 平均 | O(n²) | |
| 最差 | O(n²) | |
| 空間 | O(1) | 原地排序 |
原始碼中 getIndexOfSmallest 條件判斷有誤:
// 原始碼錯誤
if (arrays[smallFlag] > arrays[j]) // 應為 <
smallFlag = j;
// 修正後
if (arrays[smallFlag] > arrays[j]) // 尋找最小值
smallFlag = j;
正確邏輯:smallFlag 記錄目前最小值索引,發現更小則更新。
| 演算法 | 比較次數 | 交換次數 | 穩定性 | 適應性 |
|---|---|---|---|---|
| 選擇排序 | 固定 O(n²) | O(n) | 不穩定 | 無 |
| 氣泡排序 | O(n²) | O(n²) | 穩定 | 有(優化版) |
| 插入排序 | O(n²) | O(n²) | 穩定 | 強 |
選擇排序雖非實務首選,但其「選擇-交換」模式是理解堆積排序的基礎。堆積排序正是將「線性掃描找最小」優化為「堆結構 O(log n) 取最小」,將整體複雜度降為 O(n log n)。