PHP 快速排序算法
最后修改于 2025 年 4 月 16 日
基本定义
一个算法是解决问题的逐步过程。在编程中,算法被实现为函数或方法。
排序意味着将数据按特定顺序排列,通常是升序或降序。高效的排序对于许多应用程序至关重要。
常见的排序算法包括
- 快速排序
- 归并排序
- 气泡排序
- 插入排序
- 选择排序
- 堆排序
快速排序概述
快速排序是一种分治算法。它通过选择一个“枢轴”元素并将数组围绕该枢轴进行分区来工作。它具有 O(n log n) 的平均时间复杂度,这使得它对大型数据集非常有效。
基本快速排序实现
这是一个用 PHP 对数字数据进行快速排序的基本实现
quick_sort_basic.php
<?php function quickSort(array $array): array { if (count($array) <= 1) { return $array; } $pivot = $array[0]; $left = $right = []; for ($i = 1; $i < count($array); $i++) { if ($array[$i] < $pivot) { $left[] = $array[$i]; } else { $right[] = $array[$i]; } } return array_merge( quickSort($left), [$pivot], quickSort($right) ); } $numbers = [3, 6, 8, 10, 1, 2, 1]; $sorted = quickSort($numbers); print_r($sorted); // Outputs: [1, 1, 2, 3, 6, 8, 10]
此实现通过将元素分区为左(小于枢轴)和右(大于枢轴)子数组来递归地对数组进行排序。
对文本数据进行排序
快速排序也可以按字母顺序对字符串进行排序。这里有一个例子
quick_sort_strings.php
<?php function quickSortStrings(array $array): array { if (count($array) <= 1) { return $array; } $pivot = $array[0]; $left = $right = []; for ($i = 1; $i < count($array); $i++) { if (strcmp($array[$i], $pivot) < 0) { $left[] = $array[$i]; } else { $right[] = $array[$i]; } } return array_merge( quickSortStrings($left), [$pivot], quickSortStrings($right) ); } $names = ["John", "Alice", "Bob", "Eve", "Charlie"]; $sortedNames = quickSortStrings($names); print_r($sortedNames); // Outputs: ["Alice", "Bob", "Charlie", "Eve", "John"]
此版本使用 strcmp
来比较字符串。该算法的工作方式与数字相同,只是使用了不同的比较逻辑。
降序排序
要按降序排序,我们只需反转比较逻辑
quick_sort_descending.php
<?php function quickSortDesc(array $array): array { if (count($array) <= 1) { return $array; } $pivot = $array[0]; $left = $right = []; for ($i = 1; $i < count($array); $i++) { if ($array[$i] > $pivot) { $left[] = $array[$i]; } else { $right[] = $array[$i]; } } return array_merge( quickSortDesc($left), [$pivot], quickSortDesc($right) ); } $numbers = [3, 6, 8, 10, 1, 2, 1]; $sortedDesc = quickSortDesc($numbers); print_r($sortedDesc); // Outputs: [10, 8, 6, 3, 2, 1, 1]
唯一的改变是将比较运算符从 <
更改为 >
。这会将较大的元素放入左侧数组,从而产生降序。
优化快速排序
基本实现可以通过使用原地分区和随机枢轴选择来进行优化
quick_sort_optimized.php
<?php function quickSortOptimized(array &$array, int $low, int $high): void { if ($low < $high) { $pi = partition($array, $low, $high); quickSortOptimized($array, $low, $pi - 1); quickSortOptimized($array, $pi + 1, $high); } } function partition(array &$array, int $low, int $high): int { $pivot = $array[$high]; $i = $low - 1; for ($j = $low; $j <= $high - 1; $j++) { if ($array[$j] < $pivot) { $i++; [$array[$i], $array[$j]] = [$array[$j], $array[$i]]; } } [$array[$i + 1], $array[$high]] = [$array[$high], $array[$i + 1]]; return $i + 1; } $numbers = [3, 6, 8, 10, 1, 2, 1]; quickSortOptimized($numbers, 0, count($numbers) - 1); print_r($numbers); // Outputs: [1, 1, 2, 3, 6, 8, 10]
此版本原地排序,不创建新数组,从而减少内存使用。它还使用最后一个元素作为枢轴,可以将其随机化,以便在近乎排序的数据上获得更好的性能。
快速排序与插入排序基准测试
让我们将快速排序与插入排序进行比较,看看性能差异
sort_benchmark.php
<?php function insertionSort(array $array): array { for ($i = 1; $i < count($array); $i++) { $key = $array[$i]; $j = $i - 1; while ($j >= 0 && $array[$j] > $key) { $array[$j + 1] = $array[$j]; $j--; } $array[$j + 1] = $key; } return $array; } // Generate large array $largeArray = []; for ($i = 0; $i < 10000; $i++) { $largeArray[] = rand(1, 100000); } // Quick Sort benchmark $start = microtime(true); quickSortOptimized($largeArray, 0, count($largeArray) - 1); $quickTime = microtime(true) - $start; // Insertion Sort benchmark $start = microtime(true); insertionSort($largeArray); $insertionTime = microtime(true) - $start; echo "Quick Sort time: " . number_format($quickTime, 5) . " seconds\n"; echo "Insertion Sort time: " . number_format($insertionTime, 5) . " seconds\n";
在具有 10,000 个元素的典型机器上,您将看到类似的结果
Quick Sort time: 0.01234 seconds Insertion Sort time: 1.23456 seconds
对于大型数据集,快速排序明显更快,因为它具有 O(n log n) 的平均时间复杂度,而插入排序的复杂度为 O(n²)。
何时使用快速排序
- 大型数据集: 快速排序在大型集合中表现出色。
- 平均情况性能: 当 O(n log n) 可以接受时。
- 内存限制: 原地版本使用最少的内存。
何时避免快速排序
- 近乎排序的数据: 如果没有优化,可能会降低到 O(n²)。
- 需要稳定性: 快速排序不是一个稳定的排序算法。
- 小型数据集: 更简单的算法可能更有效。
来源
本教程介绍了 PHP 中的快速排序算法,并提供了数字和文本数据的示例,包括与插入排序的性能比较。
作者
列出 所有 PHP 教程。