冒泡排序通過重複遍歷數組,比較相鄰元素並交換順序,使較大(或較小)元素逐漸「冒泡」到數組末端。雖時間複雜度為 O(n²),但因原理直觀、代碼簡潔,是教學入門經典。
<?php
$arr = [345, 4, 17, 6, 52, 16, 58, 69, 32, 8, 234];
$n = count($arr);
// 外層控制遍歷輪數(需 n-1 輪)
for ($i = 1; $i < $n; $i++) {
// 內層從末尾向前比較相鄰元素
// 第 i 輪結束後,最後 i 個元素已有序,無需再比較
for ($j = $n - 1; $j >= $i; $j--) {
if ($arr[$j] < $arr[$j - 1]) {
// 交換
$temp = $arr[$j - 1];
$arr[$j - 1] = $arr[$j];
$arr[$j] = $temp;
}
}
}
print_r($arr);
// 結果:[4, 6, 8, 16, 17, 32, 52, 58, 69, 234, 345]
| 輪次 | 比較過程 | 輪次結束狀態 |
|---|---|---|
| 1 | (3,1)→交換 (3,4)→無 (4,2)→交換 | [1, 3, 2, 4] ← 最大值 4 就位 |
| 2 | (1,3)→無 (3,2)→交換 | [1, 2, 3, 4] ← 次大值 3 就位 |
| 3 | (1,2)→無 | [1, 2, 3, 4] ← 排序完成 |
function bubbleSortOptimized(array &$arr): void
{
$n = count($arr);
for ($i = 1; $i < $n; $i++) {
$swapped = false;
for ($j = $n - 1; $j >= $i; $j--) {
if ($arr[$j] < $arr[$j - 1]) {
[$arr[$j - 1], $arr[$j]] = [$arr[$j], $arr[$j - 1]]; // PHP 7.1+ 解構賦值交換
$swapped = true;
}
}
// 本輪無交換,說明已有序
if (!$swapped) break;
}
}
效果: 最好情況(已有序)時間複雜度降為 O(n)。
function cocktailSort(array &$arr): void
{
$left = 0;
$right = count($arr) - 1;
while ($left < $right) {
// 正向:將最大值移到右端
for ($i = $left; $i < $right; $i++) {
if ($arr[$i] > $arr[$i + 1]) {
[$arr[$i], $arr[$i + 1]] = [$arr[$i + 1], $arr[$i]];
}
}
$right--;
// 反向:將最小值移到左端
for ($i = $right; $i > $left; $i--) {
if ($arr[$i] < $arr[$i - 1]) {
[$arr[$i], $arr[$i - 1]] = [$arr[$i - 1], $arr[$i]];
}
}
$left++;
}
}
優勢: 減少「烏龜」(小值在右端需慢速左移)問題,實際運行約快 20-30%。
| 指標 | 數值 | 說明 |
|---|---|---|
| 最好時間複雜度 | O(n) | 優化版,數組已有序 |
| 平均時間複雜度 | O(n²) | ≈ n²/4 次比較與交換 |
| 最壞時間複雜度 | O(n²) | 逆序數組,≈ n²/2 次操作 |
| 空間複雜度 | O(1) | 原地排序,僅需常數額外空間 |
| 穩定性 | 穩定 | 相等元素相對順序不變 |
<?php
$arr = [345, 4, 17, 6, 52, 16, 58, 69, 32, 8, 234];
// 1. sort() - 快速排序(C 實現,極快)
sort($arr);
// 2. asort() - 保持鍵值關聯
// 3. usort() - 自定義比較
usort($arr, fn($a, $b) => $a <=> $b); // PHP 7+ 太空船操作符
// 性能對比(10萬隨機整數)
// 冒泡排序:~15-30 秒
// sort():~0.01 秒
// 差距:3-4 個數量級!
sort()、rsort()、asort()、ksort() — C 級性能,經過大規模驗證usort($arr, fn($a, $b) => $a['priority'] <=> $b['priority'])array_multisort() 或 usort 組合邏輯