关于php下合并排序的问题

时间:2009-12-29 16:32:51

标签: php algorithm sorting

我一直在尝试在php下实现合并排序。但似乎不成功:(找不到错误的来源。非常感谢任何形式的帮助!

function merge_sort(&$input, $start, $end) {
    if($start < $end) {
        $mid = (int) floor($start + $end / 2);
        merge_sort($input, $start, $mid);
        merge_sort($input, $mid + 1, $end);
        merge($input, $start, $mid, $end);
    } 
}

function merge(&$input, $p, $q, $r) { 
    $a = $q - $p + 1;
    $b = $r - $q;

    for($i = $p;$i <= $q;$i++) {
        $arr1[] = $input[$i];
    }

    for($i = $q+1;$i <= $r;$i++) {
        $arr2[] = $input[$i];
    }   

    $c = $d = 0;
    for($i = $p; $i <= $r; $i++) {
        $s = $arr1[$c];
        $t = $arr2[$d];

        if($a && (($s <= $t) || !$b)) { 
            $input[$i] = $s;
            $a--;$c++;
        } else if($b) {
            $input[$i] = $t;
            $b--;$d++;
        }
    } 
    return true;
}

这是信息xdebug扔回来:

Fatal error: Maximum function nesting level of '100' reached, aborting! 

7 个答案:

答案 0 :(得分:8)

要在合并排序上达到100的嵌套级别,您需要具有大小为2^100(大约1e30)的输入数组,这是不可能的。我怀疑你的递归是不正确的。例如,您写了$start + $end / 2而不是($start + $end) / 2

答案 1 :(得分:1)

xdebug.max_nesting_level=500 

在我的php.ini

答案 2 :(得分:1)

这是我的工作解决方案,随意比较...

/**
 * @param array $items array to sort
 * @param int   $l     left index (defaults to 0)
 * @param int   $r     right index (defaults to count($items)-1)
 */
function mergeSort(&$items, $l = 0, $r = null)
{
    if (!isset($r)) {
        $r = count($items) - 1;
    }

    if ($l < $r) {
        $m = floor(($r - $l) / 2) + $l;
        mergeSort($items, $l, $m);
        mergeSort($items, $m + 1, $r);
        merge($items, $l, $m, $r);
    }
}

/**
 * @param array $items array to merge
 * @param int   $l     left index
 * @param int   $m     middle index
 * @param int   $r     right index
 */
function merge(&$items, $l, $m, $r)
{
    $itemsA = array_slice($items, $l, $m + 1 - $l);
    $itemsB = array_slice($items, $m + 1, ($r + 1) - ($m + 1));

    $a = 0;
    $aCount = count($itemsA);
    $b = 0;
    $bCount = count($itemsB);

    for ($i = $l; $i <= $r; $i++) {
        if ($a < $aCount && ($b == $bCount || $itemsA[$a] <= $itemsB[$b])) {
            $items[$i] = $itemsA[$a++];
        } else {
            $items[$i] = $itemsB[$b++];
        }
    }
}

$items = array(5,3,6,1,2,3,9,10,7,2,4,8);
mergeSort($items);
echo implode(',', $items) . "\n";

输出:

1,2,2,3,3,4,5,6,7,8,9,10

答案 3 :(得分:0)

最大功能嵌套级别为“100”,您已达到它。你的递归函数太深了。

答案 4 :(得分:0)

来自http://www.xdebug.org/docs/all_settings

  

xdebug.max_nesting_level   类型:整数,默认值:100   控制无限递归保护的保护机制。此设置的值是在中止脚本之前允许的最大嵌套函数级别。

你的递归函数太深了,触发了这个xdebug错误。尝试提高此限制,看看是否有帮助。

此外,这是一篇关于递归和PHP的有趣文章:http://www.alternateinterior.com/2006/09/tail-recursion-in-php.html

答案 5 :(得分:0)

PHP不是递归算法的好语言。来自manual

  

可以调用递归   PHP中的函数。但要避免   用递归函数/方法调用   超过100-200递归水平   可以粉碎堆栈并导致一个   终止当前的脚本。

如果您需要在PHP中执行此操作,则可能必须找到该算法的迭代版本。您已达到该语言的硬编码限制。

答案 6 :(得分:0)

Cosi dovrebbe funzionare !!!! www.dslpg.it

function merge ( &$a, $left,  $center, $right ) { //left = p   right = r  center = q
    $n1 = $center - $left + 1;
    $n2 = $right - $center;
    for ($i = 1; $i <= $n1; $i++) $L[$i] = $a[$left+$i-1];
    for ($i = 1; $i <= $n2; $i++) $R[$i] = $a[$center+$i];
    $L[$n1+1] = 99999;
    $R[$n2+1] = 99999; 
    $i = 1;
    $j = 1;
    for ($k = $left; $k <= $right; $k++) {
        if ($L[$i] <= $R[$j] ) {
            $a[$k] = $L[$i];
            echo $a[$k];
            $i++;
        }
        else {
            $a[$k] = $R[$j];
            echo $a[$k];
            $j++;
        }
    }
    return $a;
}
function merge_sort ( &$a, $left, $right ) { //left = p  right = r
    if ( $left < $right ) {
        $center = (int) floor(($left + $right) / 2 );

        merge_sort ($a, $left, $center);
        merge_sort ($a, $center+1, $right);
        merge ($a, $left, $center, $right);
    }
}
merge_sort ( $a, 1, $n );