PHP 桶排序算法
最后修改于 2025 年 4 月 16 日
基本定义
一个算法是解决问题的分步过程。它接受输入,并按照一组定义的规则产生输出。
排序将数据按特定顺序排列(升序或降序)。有效的排序对于优化其他算法至关重要。
常见的排序算法包括
- 气泡排序
- 选择排序
- 插入排序
- 归并排序
- 快速排序
- 堆排序
- 桶排序
- 基数排序
桶排序概述
桶排序将元素分配到桶中,对每个桶进行排序,然后将它们连接起来。当输入均匀分布时,效果很好。
时间复杂度:最佳情况为 O(n + k),最坏情况为 O(n²)。空间复杂度:O(n + k),其中 k 是桶的数量。
数字桶排序(升序)
此示例使用桶排序按升序对数字进行排序。
numeric_ascending.php
<?php
function bucketSort(array $numbers): array {
$min = min($numbers);
$max = max($numbers);
$bucketCount = count($numbers);
$range = ($max - $min) / $bucketCount;
$buckets = array_fill(0, $bucketCount, []);
foreach ($numbers as $num) {
$index = floor(($num - $min) / $range);
$index = min($index, $bucketCount - 1);
$buckets[$index][] = $num;
}
$sorted = [];
foreach ($buckets as $bucket) {
sort($bucket);
$sorted = array_merge($sorted, $bucket);
}
return $sorted;
}
$numbers = [0.42, 0.32, 0.23, 0.52, 0.25, 0.47, 0.51];
$sorted = bucketSort($numbers);
print_r($sorted);
输出显示按升序排序的数字。该算法首先根据数值范围将数字分配到桶中。
数字桶排序(降序)
这修改了前面的示例,以按降序排序。
numeric_descending.php
<?php
function bucketSortDesc(array $numbers): array {
$min = min($numbers);
$max = max($numbers);
$bucketCount = count($numbers);
$range = ($max - $min) / $bucketCount;
$buckets = array_fill(0, $bucketCount, []);
foreach ($numbers as $num) {
$index = floor(($num - $min) / $range);
$index = min($index, $bucketCount - 1);
$buckets[$index][] = $num;
}
$sorted = [];
foreach ($buckets as $bucket) {
rsort($bucket);
$sorted = array_merge($sorted, $bucket);
}
return $sorted;
}
$numbers = [0.42, 0.32, 0.23, 0.52, 0.25, 0.47, 0.51];
$sorted = bucketSortDesc($numbers);
print_r($sorted);
关键的变化是使用rsort()而不是sort()在合并之前按降序对各个桶进行排序。
字符串桶排序(升序)
桶排序也可以按字母顺序对字符串进行排序。此示例演示了如何操作。
string_ascending.php
<?php
function bucketSortStrings(array $strings): array {
$minOrd = ord('a');
$maxOrd = ord('z');
$bucketCount = 26; // One for each letter
$buckets = array_fill(0, $bucketCount, []);
foreach ($strings as $str) {
$firstChar = strtolower(substr($str, 0, 1));
$index = ord($firstChar) - $minOrd;
$buckets[$index][] = $str;
}
$sorted = [];
foreach ($buckets as &$bucket) {
sort($bucket);
$sorted = array_merge($sorted, $bucket);
}
return $sorted;
}
$names = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank"];
$sorted = bucketSortStrings($names);
print_r($sorted);
字符串根据其首字母分配到桶中。然后,在合并之前,每个桶按字母顺序排序。
字符串桶排序(降序)
此版本按逆字母顺序对字符串进行排序。
string_descending.php
<?php
function bucketSortStringsDesc(array $strings): array {
$minOrd = ord('a');
$maxOrd = ord('z');
$bucketCount = 26;
$buckets = array_fill(0, $bucketCount, []);
foreach ($strings as $str) {
$firstChar = strtolower(substr($str, 0, 1));
$index = ord($firstChar) - $minOrd;
$buckets[$index][] = $str;
}
$sorted = [];
foreach ($buckets as &$bucket) {
rsort($bucket);
$sorted = array_merge($sorted, $bucket);
}
return array_reverse($sorted);
}
$names = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank"];
$sorted = bucketSortStringsDesc($names);
print_r($sorted);
我们使用rsort()用于桶,使用array_reverse()用于最终结果,以获得降序字母顺序。
桶排序 vs 快速排序基准测试
让我们比较一下桶排序和快速排序在大型数据集上的性能。
benchmark.php
<?php
function quickSort(array $array): array {
if (count($array) < 2) {
return $array;
}
$pivot = $array[0];
$less = $greater = [];
for ($i = 1; $i < count($array); $i++) {
if ($array[$i] <= $pivot) {
$less[] = $array[$i];
} else {
$greater[] = $array[$i];
}
}
return array_merge(quickSort($less), [$pivot], quickSort($greater));
}
// Generate large random dataset
$largeData = [];
for ($i = 0; $i < 10000; $i++) {
$largeData[] = mt_rand(0, 10000) / 100;
}
// Benchmark bucket sort
$start = microtime(true);
bucketSort($largeData);
$bucketTime = microtime(true) - $start;
// Benchmark quick sort
$start = microtime(true);
quickSort($largeData);
$quickTime = microtime(true) - $start;
echo "Bucket Sort Time: " . number_format($bucketTime, 6) . " seconds\n";
echo "Quick Sort Time: " . number_format($quickTime, 6) . " seconds\n";
结果会有所不同,但通常快速排序在一般情况下优于桶排序。当数据均匀分布时,桶排序表现出色。
何时使用桶排序
- 均匀分布:当输入均匀分布时
- 已知范围:当数据范围提前已知时
- 浮点数:特别适用于浮点数
- 外部排序:适用于外部排序场景
来源
本教程涵盖了 PHP 实现的桶排序,并提供了数值和文本数据升序和降序的示例。
作者
列出 所有 PHP 教程。