microtime(true) 微秒級計時function bubbleSort(array &$arr) {
$n = count($arr);
for ($i = 0; $i < $n - 1; $i++) {
for ($j = 0; $j < $n - 1 - $i; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
[$arr[$j], $arr[$j + 1]] = [$arr[$j + 1], $arr[$j]];
}
}
}
}
function selectSort(array &$arr) {
$n = count($arr);
for ($i = 0; $i < $n - 1; $i++) {
$minIdx = $i;
for ($j = $i + 1; $j < $n; $j++) {
if ($arr[$j] < $arr[$minIdx]) $minIdx = $j;
}
if ($minIdx !== $i) [$arr[$i], $arr[$minIdx]] = [$arr[$minIdx], $arr[$i]];
}
}
function insertSort(array &$arr) {
$n = count($arr);
for ($i = 1; $i < $n; $i++) {
$key = $arr[$i];
$j = $i - 1;
while ($j >= 0 && $arr[$j] > $key) {
$arr[$j + 1] = $arr[$j];
$j--;
}
$arr[$j + 1] = $key;
}
}
function quickSort(array $arr): array {
if (count($arr) <= 1) return $arr;
$pivot = $arr[0];
$left = $right = [];
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] < $pivot) $left[] = $arr[$i];
elseif ($arr[$i] > $pivot) $right[] = $arr[$i];
}
return array_merge(quickSort($left), [$pivot], quickSort($right));
}
$data = range(1, 3000);
shuffle($data);
$testData = array_slice($data, 0, 1600); // 取前 1600 個
$algos = [
'冒泡排序' => 'bubbleSort',
'選擇排序' => 'selectSort',
'插入排序' => 'insertSort',
'快速排序' => 'quickSort',
];
foreach ($algos as $name => $func) {
$arr = $testData; // 每次複製原數據
$start = microtime(true);
$func($arr);
$elapsed = (microtime(true) - $start) * 1000;
echo "$name 耗時: " . number_format($elapsed, 2) . " ms\n";
}
| 算法 | 耗時 (ms) | 時間複雜度 | 空間複雜度 | 穩定性 |
|---|---|---|---|---|
| 冒泡排序 | ~450 | O(n²) | O(1) | 穩定 |
| 選擇排序 | ~120 | O(n²) | O(1) | 不穩定 |
| 插入排序 | ~85 | O(n²) / 最好 O(n) | O(1) | 穩定 |
| 快速排序 | ~3 | O(n log n) | O(log n) | 不穩定 |
永遠不要在業務代碼手寫排序! 直接用
sort()/usort()/asort()等內置函數,底層實現為 Zend Engine C 級快速排序(Zend_qsort),經過高度優化,並支援自定義比較函數。
// 內置函數示例 $arr = [3, 1, 4, 1, 5, 9]; sort($arr); // 升序,重置鍵 rsort($arr); // 降序 usort($arr, fn($a, $b) => $a <=> $b); // 太空船操作符(PHP 7+) asort($arr); // 保持鍵值關聯升序 ksort($arr); // 按鍵名排序
$users = [
['name' => 'A', 'age' => 25, 'score' => 90],
['name' => 'B', 'age' => 20, 'score' => 95],
['name' => 'C', 'age' => 25, 'score' => 85],
];
// 多字段排序:年齡升序,同齡分數降序
usort($users, function($a, $b) {
return [$a['age'], -$a['score']] <=> [$b['age'], -$b['score']];
});
/* 結果:
B (20, 95)
A (25, 90)
C (25, 85)
*/
理解排序算法複雜度是計算機科學基礎,但 PHP 開發中 「不造輪子」是鐵律。本文實測旨在建立直觀性能認知:O(n log n) vs O(n²) 的差距在 1,000+ 數據量即顯現。面試、教學、極少數無法用內置函數的場景(如自定義數據結構)才需手寫。日常開發請信賴 sort() 族函數,它們是經過百萬行生產代碼驗證的最優解。