將數組分為「已排序區」和「未排序區」,每次從未排序區取首元素,在已排序區從右向左比較、位移,找到插入位置。類似整理撲克牌。
function insertSort(array $a): array {
$n = count($a);
for ($i = 1; $i < $n; $i++) {
$temp = $a[$i];
$j = $i - 1;
// 從右向左查找插入位置,同時後移元素
while ($j >= 0 && $temp < $a[$j]) {
$a[$j + 1] = $a[$j];
$j--;
}
$a[$j + 1] = $temp; // 插入
}
return $a;
}
| 指標 | 數值 | 說明 |
|---|---|---|
| 時間複雜度(最好) | O(n) | 已有序,內層 while 不執行 |
| 時間複雜度(最壞/平均) | O(n²) | 逆序/隨機,需大量位移 |
| 空間複雜度 | O(1) | 原地排序,僅常數輔助變量 |
| 穩定性 | 穩定 | 相等元素不交換順序 |
function randomNumber(int $size = 10): array {
$arr = [];
for ($i = 0; $i < $size; $i++) $arr[] = mt_rand(0, 1000);
return $arr;
}
$a = randomNumber(20);
echo "Unsorted: ".implode(' ', $a)."\n";
echo "Sorted: ".implode(' ', insertSort($a))."\n";
將線性查找優化為 O(log n),但元素位移仍為 O(n²),適合「比較成本高、移動成本低」的場景(如大對象排序)。
function binaryInsertSort(array $a): array {
$n = count($a);
for ($i = 1; $i < $n; $i++) {
$temp = $a[$i];
$left = 0; $right = $i - 1;
while ($left <= $right) {
$mid = ($left + $right) >> 1;
if ($temp < $a[$mid]) $right = $mid - 1;
else $left = $mid + 1;
}
for ($j = $i - 1; $j >= $left; $j--) $a[$j + 1] = $a[$j];
$a[$left] = $temp;
}
return $a;
}
插入排序的改進版,按增量分組預排序,最終增量為 1 時退化為插入排序,平均 O(n^1.3)。
sort())。