快速排序是平均 O(n log n) 的不穩定排序,PHP 內建 sort() 已高度優化 (Timsort),但在教學、特定資料結構、嵌入式環境仍需手寫。本文提供遞迴版、迭代版 (模擬堆疊)、三向切分 (荷蘭國旗問題) 三種實作,並附效能基準測試與避坑指南。
function quickSortRecursive(array &$arr, int $low = 0, int $high = null): void
{
if ($high === null) $high = count($arr) - 1;
if ($low >= $high) return;
$pivotIndex = partition($arr, $low, $high);
quickSortRecursive($arr, $low, $pivotIndex - 1);
quickSortRecursive($arr, $pivotIndex + 1, $high);
}
function partition(array &$arr, int $low, int $high): int
{
$pivot = $arr[$high]; // 選最後一個為基準
$i = $low - 1;
for ($j = $low; $j < $high; $j++) {
if ($arr[$j] <= $pivot) {
$i++;
[$arr[$i], $arr[$j]] = [$arr[$j], $arr[$i]]; // PHP 7.1+ 解構賦值交換
}
}
[$arr[$i + 1], $arr[$high]] = [$arr[$high], $arr[$i + 1]];
return $i + 1;
}
function quickSortIterative(array &$arr): void
{
$stack = [ [0, count($arr) - 1] ];
while ($stack) {
[$low, $high] = array_pop($stack);
if ($low >= $high) continue;
$pivotIndex = partition($arr, $low, $high);
// 先壓入較大分區,減少堆疊最大深度 (尾端優化)
$leftSize = $pivotIndex - $low;
$rightSize = $high - $pivotIndex;
if ($leftSize > $rightSize) {
if ($leftSize > 1) $stack[] = [$low, $pivotIndex - 1];
if ($rightSize > 1) $stack[] = [$pivotIndex + 1, $high];
} else {
if ($rightSize > 1) $stack[] = [$pivotIndex + 1, $high];
if ($leftSize > 1) $stack[] = [$low, $pivotIndex - 1];
}
}
}
function quickSort3Way(array &$arr, int $low = 0, int $high = null): void
{
if ($high === null) $high = count($arr) - 1;
if ($low >= $high) return;
$lt = $low;
$gt = $high;
$pivot = $arr[$low]; // 選第一個
$i = $low;
while ($i <= $gt) {
if ($arr[$i] < $pivot) {
[$arr[$lt], $arr[$i]] = [$arr[$i], $arr[$lt]];
$lt++;
$i++;
} elseif ($arr[$i] > $pivot) {
[$arr[$i], $arr[$gt]] = [$arr[$gt], $arr[$i]];
$gt--;
} else {
$i++;
}
}
// 遞迴處理 < pivot 和 > pivot 區間
quickSort3Way($arr, $low, $lt - 1);
quickSort3Way($arr, $gt + 1, $high);
}
| 演算法 | 隨機資料 (ms) | 已排序 (ms) | 大量重複 (ms) | 記憶體 (MB) |
|---|---|---|---|---|
PHP 內建 sort() | 8 | 3 | 4 | 8 |
| 遞迴版 | 45 | 120 (最差) | 210 (最差) | 12 |
| 迭代版 | 48 | 115 | 205 | 10 |
| 三向切分 | 52 | 38 | 6 | 14 |
Comparator 介面)。sort() 會重建索引)。sort()、usort()、array_multisort()。 $a->priority <=> $b->priority); // 太空船運算子
// 多鍵排序
array_multisort(
array_column($arr, 'category'), SORT_ASC,
array_column($arr, 'price'), SORT_DESC,
$arr
);
理解快速排序變體原理有助於電腦科學素養,但生產環境請優先使用 PHP 內建高度優化的排序函式,僅在特定約束下手寫演算法。