插入排序是簡單直觀的排序演算法,適合小規模或近乎有序資料。本文提供生產級實作:採用單例模式封裝、支援 int[] 與泛型 T[]、完整邊界檢查、哨兵優化,並附測試驗證。
array[i] 小於前一個值 array[i-1],啟動內層插入i-1 向前掃描,將大於哨兵值的元素向後搬移時間複雜度:最佳 O(n) (已排序)、最差/平均 O(n²)、空間 O(1)、穩定排序。
public final class Swapper {
private Swapper() {}
public static > void swap(int i, int j, T[] arr) {
if (arr == null) throw new NullPointerException("array is null");
checkIndices(i, j, arr.length);
T tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
public static void swap(int i, int j, int[] arr) {
if (arr == null) throw new NullPointerException("array is null");
checkIndices(i, j, arr.length);
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
private static void checkIndices(int i, int j, int len) {
if (i < 0 || j < 0 || i >= len || j >= len)
throw new IllegalArgumentException("Index out of bounds: [" + i + "," + j + "]");
}
}
public final class InsertionSortord {
private static final InsertionSortord INSTANCE = new InsertionSortord();
private InsertionSortord() {}
public static InsertionSortord getInstance() { return INSTANCE; }
// int[] 版本
public void doSort(int... array) {
if (array == null || array.length <= 1) return;
for (int i = 1; i < array.length; i++) {
if (array[i] < array[i - 1]) {
int sentry = array[i];
int vacancy = i;
for (int j = i - 1; j >= 0; j--) {
if (array[j] > sentry) {
array[j + 1] = array[j];
vacancy = j;
}
}
array[vacancy] = sentry;
}
}
}
// 泛型版本 (支援任何 Comparable)
public > void doSortT(T[] array) {
if (array == null || array.length <= 1) return;
for (int i = 1; i < array.length; i++) {
if (array[i].compareTo(array[i - 1]) < 0) {
T sentry = array[i];
int vacancy = i;
for (int j = i - 1; j >= 0; j--) {
if (array[j].compareTo(sentry) > 0) {
array[j + 1] = array[j];
vacancy = j;
}
}
array[vacancy] = sentry;
}
}
}
}
public class TestInsertionSortord {
public static void main(String[] args) {
InsertionSortord sorter = InsertionSortord.getInstance();
int[] arr1 = {3, 5, 4, 2, 6};
System.out.println("Before: " + Arrays.toString(arr1));
sorter.doSort(arr1);
System.out.println("After: " + Arrays.toString(arr1));
Integer[] arr2 = {3, 5, 4, 2, 6};
System.out.println("Before: " + Arrays.toString(arr2));
sorter.doSortT(arr2);
System.out.println("After: " + Arrays.toString(arr2));
}
}
| 特性 | 說明 |
|---|---|
| 單例模式 | 無狀態工具類適合單例,避免重複建構 |
| 哨兵優化 | 減少陣列存取次數,內層迴圈只比較不交換 |
| 泛型支援 | T extends Comparable<T> 確保型別安全與比較能力 |
| 參數驗證 | 空陣列、長度 1 直接返回;索引越界拋出明確異常 |
| 可變參數 | int... array 允許 doSort(3,1,2) 或 doSort(arr) |
Arrays.sort() (Dual-Pivot QuickSort) 或 Collections.sort() (TimSort)此實作展示了演算法教學與工程化落地的平衡,可直接納入專案工具庫或作為面試手寫參考。