用 PHP 编写合并排序
我尝试在 PHP 中编写一个涉及小数组的基本合并排序,但问题是它需要大约一分钟左右的时间来执行,并返回:
致命错误:允许的内存大小 536870912 字节已耗尽(已尝试 分配 35 个字节)在 /Users/web/www/merge.php 第 39 行
有谁知道代码可能出问题的地方(如果有的话)?我已经盯着这个看了一个小时了。
<?php
$array = array(8,1,2,5,6,7);
print_array($array);
merge_sort($array);
print_array($array);
function merge_sort(&$list){
if( count($list) <= 1 ){
return $list;
}
$left = array();
$right = array();
$middle = (int) ( count($list)/2 );
// Make left
for( $i=0; $i < $middle; $i++ ){
$left[] = $list[$i];
}
// Make right
for( $i = $middle; $i < count($list); $i++ ){
$right[] = $list[$i];
}
// Merge sort left & right
merge_sort($left);
merge_sort($right);
// Merge left & right
return merge($left, $right);
}
function merge(&$left, &$right){
$result = array();
while(count($left) > 0 || count(right) > 0){
if(count($left) > 0 && count(right) > 0){
if($left[0] <= $right[0]){
$result[] = array_shift($left);
} else {
$result[] = array_shift($right);
}
} elseif (count($left) > 0){
$result[] = array_shift($left);
} elseif (count($right) > 0){
$result[] = array_shift($right);
}
}
print_array($result);exit;
return $result;
}
function print_array($array){
echo "<pre>";
print_r($array);
echo "<br/>";
echo "</pre>";
}
?>
I have tried to write a basic merge sort in PHP involving a small array, yet the problem is it takes about a minute or so to execute, and returns:
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried
to allocate 35 bytes) in /Users/web/www/merge.php on line 39
Does anyone have an idea where the code might be going wrong (if at all)? I've been staring at this for a good hour now.
<?php
$array = array(8,1,2,5,6,7);
print_array($array);
merge_sort($array);
print_array($array);
function merge_sort(&$list){
if( count($list) <= 1 ){
return $list;
}
$left = array();
$right = array();
$middle = (int) ( count($list)/2 );
// Make left
for( $i=0; $i < $middle; $i++ ){
$left[] = $list[$i];
}
// Make right
for( $i = $middle; $i < count($list); $i++ ){
$right[] = $list[$i];
}
// Merge sort left & right
merge_sort($left);
merge_sort($right);
// Merge left & right
return merge($left, $right);
}
function merge(&$left, &$right){
$result = array();
while(count($left) > 0 || count(right) > 0){
if(count($left) > 0 && count(right) > 0){
if($left[0] <= $right[0]){
$result[] = array_shift($left);
} else {
$result[] = array_shift($right);
}
} elseif (count($left) > 0){
$result[] = array_shift($left);
} elseif (count($right) > 0){
$result[] = array_shift($right);
}
}
print_array($result);exit;
return $result;
}
function print_array($array){
echo "<pre>";
print_r($array);
echo "<br/>";
echo "</pre>";
}
?>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在您的
merge
函数中,您调用right
上的 count 而不是$right
。 PHP 假定这是一个字符串常量(至少在 5.3.9 中),并且当转换为始终具有一个元素的数组时。因此count(right)
始终为 1,并且您永远不会退出第一次合并。In your
merge
function, you call count onright
instead of$right
. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. Socount(right)
is always one, and you never exit the first merge.尝试这种方法。不要移动它,而是切片。
另外,对于
merge
函数的 in while 循环,您需要进行和&&
比较||
Try this approach. Instead of shifting it, slice.
Also, for in while loop for the
merge
function, you need to do an and&&
comparison insteadof
||
看看这个,算法已经实现了,使用 array_push 和 array splice 而不是仅仅 array_shift。
Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.
我这样实现合并排序
I implement merge sort this way
这是 PHP 中实现合并排序的类 -
Here is the class in PHP to implement the Merge Sort -
我一直在寻找 PHP 中优化的合并排序算法。答案中有 5 种算法,所以我测试了这些算法,也测试了我的算法。使用 PHP 7.2.7,时间如下:
对 1000 个随机数进行排序:
对 10 个随机数进行排序:
所以,尽管我鼓励谁阅读它以使其更快(这是我一直在寻找的,并且我相信它可以完成),但我也让你实现我的实现,原因似乎是比其他答案更快:
如果您发布新答案,请让我发表评论来测试它并添加它。
编辑:对于那些寻求更好实现的人,我做了一些新的优化。
I was looking for a optimized Mergesort algorithm in PHP. There are 5 algorithms in the answers, so I tested those, and mine too. Using PHP 7.2.7, these are the times:
Sorting 1000 random numbers:
Sorting 10 random numbers:
So, although I encourage to whom read it to make it faster (that was I was looking for, and I believe it can be done), I let you my implementation too, cause seems to be faster than the other answers:
If you post a new answer, let me a comment to test it and add it.
Edit: I did some new optimizations, for those looking for a better implementation.
您的合并排序通过引用接受列表
,因此您需要为其分配新的合并和排序列表。因此,不要这样做
,
只需删除退出并修复计数变量即可
Your merge sort accepts a list by reference
So you need to assign it the new merged and sorted list. So instead of
do
That should do it, just remove the exit and fix the count variable
PHP 中的归并排序
MergeSort in PHP