將數組分為有序區與無序區。初始有序區僅含第一個元素,每次從無序區取出首元素,在有序區中從後向前掃描,找到插入位置並移動元素騰出空位,完成插入。
#include <stdio.h>
#include <stdlib.h>
#define N 10
void insertion_sort(int arr[], int n) {
for (int i = 1; i < n; i++) { // 從第 2 個元素開始
int key = arr[i]; // 待插入元素
int j = i - 1;
// 有序區從右向左掃描,大於 key 的元素右移
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // 插入正確位置
}
}
void print_array(int arr[], int n) {
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n");
}
int main() {
int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int n = sizeof(arr) / sizeof(arr[0]);
printf("排序前: "); print_array(arr, n);
insertion_sort(arr, n);
printf("排序後: "); print_array(arr, n);
return 0;
}
| 步驟 | 有序區 | 待插入 | 比較/移動過程 | 結果 |
|---|---|---|---|---|
| 1 | [9] | 8 | 9>8 → 9 右移 → 插入 8 | [8, 9] |
| 2 | [8, 9] | 7 | 9>7→右移, 8>7→右移 → 插入 7 | [7, 8, 9] |
| 3 | [7, 8, 9] | 6 | 9,8,7 依次右移 → 插入 6 | [6, 7, 8, 9] |
| 4 | [6, 7, 8, 9] | 5 | 9,8,7,6 依次右移 → 插入 5 | [5, 6, 7, 8, 9] |
void binary_insertion_sort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int low = 0, high = i - 1;
// 二分查找插入位置
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] > key) high = mid - 1;
else low = mid + 1;
}
// 統一右移 [low, i-1]
for (int j = i - 1; j >= low; j--) arr[j + 1] = arr[j];
arr[low] = key;
}
}
直接插入排序以穩定、適應性強(有序度高時極快)、實現簡潔著稱,是工程中小規模排序、混合排序基例的首選算法。