首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 四大基礎排序算法性能實測:冒泡、選擇、插入、快排

     編輯:PHP 綜合知識

測試環境

  • PHP 8.1 CLI
  • 數據量:1,600 隨機整數(範圍 1-3,000)
  • 測試方式:microtime(true) 微秒級計時
  • 數據特徵:完全無序,含重複值

算法實現

1. 冒泡排序 - O(n²)

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]];
            }
        }
    }
}

2. 選擇排序 - O(n²)

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]];
    }
}

3. 插入排序 - O(n²) 最好 O(n)

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;
    }
}

4. 快速排序 - 平均 O(n log n)

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)時間複雜度空間複雜度穩定性
冒泡排序~450O(n²)O(1)穩定
選擇排序~120O(n²)O(1)不穩定
插入排序~85O(n²) / 最好 O(n)O(1)穩定
快速排序~3O(n log n)O(log n)不穩定

結果分析

  • 🚀 快排碾壓級優勢:得益於分治法,1,600 元素僅需 3ms,比 O(n²) 算法快 2-3 個數量級
  • 🐢 冒泡最慢:雙重循環 + 頻繁交換,PHP 解釋器開銷大
  • ⚖️ 插入 > 選擇 > 冒泡:插入排序在近乎有序數據極快(最好 O(n)),選擇排序交換次數少(n-1 次),冒泡交換最多
  • 💾 空間換時間:快排遞歸調用棧 + 臨時數組,空間 O(log n) 但極大提升速度

PHP 實際開發建議

永遠不要在業務代碼手寫排序! 直接用 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() 族函數,它們是經過百萬行生產代碼驗證的最優解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved