数据结构与算法之PHP递归函数

一、递归函数的定义
递归函数即自调用函数,在函数体内部直接或者间接的自己调用自己,即函数的嵌套调用是函数本身。
通常在此类型的函数题中会附加一个条件判断叙述,以判断是否需要执行递归调用,并且在特定的条件下终止函数的递归调用动作,把目前流程的主控权交回到上一层函数来执行。
<?php

//声明一个函数,用于测试递归
function test($n){
    echo $n . "  ";         //在函数开始处输出参数的值
    if ($n > 0) {           //判断参数是否大于0
        test($n-1);         //如果参数大于0则调用自己,并将参数减1后再次传入
    } else {                //判断参数不大于0
        echo "<-------->";
    }
    echo $n."  ";           //在函数结束处输出参数的值
}

//调用test函数将整数10传给参数
test(10);   

该程序执行后输出如下结果:

10 9 8 7 6 5 4 3 2 1 0 <--------> 0 1 2 3 4 5 6 7 8 9 10
解释:
第1步,执行test(10),echo 10,然后因为10>0,执行test(9),后面还有没来得及执行的echo 10;
第2步,执行test(9),echo 9,然后因为9>0,执行test(8),同样后面还有没来得及执行的 echo 9;
第3步,执行test(8),echo 8,然后因为8>0,执行test(7),同样后面还有没来得及执行的 echo 8;
第4步,执行test(7),echo 7,然后因为7>0,执行test(6),同样后面还有没来得及执行的 echo 7;
第5步,执行test(6),echo 6,然后因为6>0,执行test(5),同样后面还有没来得及执行的 echo 6;
 
...........
第10步,执行test(0),echo 0,此时0>0的条件不满足,不再执行test()函数,而是echo “<-------->”,并且执行后面的 echo 0;
这时,函数不再调用自己,将流程的主控权交回到上一层函数来执行,也就是开始执行刚刚所有test()函数没来得及输出的最后一个echo。
流程如下图:
 
在函数执行的第1步~第10步,函数输出的的是绿色部分,红色部分还“没来得及”输出,就调用自己执行操作,依次类推,直到流程执行到不再满足调用自己的条件,输出“<-->”,此时,流程该执行前面“没来得及”输出的代码。
 
二、实现递归的三种基本方式
1. 利用引用做参数
function test($a = 0, &$result = array()) {
    $a++;
    if ($a < 10) {
        $result[] = $a;
        test($a, $result);
    }
    echo $a;
    return $result;
}

该程序执行后,

  • $result数组是Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 ) 。
    以$a<10作为判断条件,条件成立,就把$a赋给$result[];将$result的引用传入函数,会将每一次递归产生的$a添加到结果数组$result中。
  • echo $a的值是10987654321,而不是12345678910。
    这是因为当$a<10的时候,在echo $a前就进行了下一次的函数递归。当$a不满足$a<10的条件时,echo $a,返回$result,并执行前几次递归函数中的echo $a。
流程如下图:
 
2. 利用全局变量
global在函数内申明变量是外部变量的同名引用。
function test($a = 0, $result = array()) {
    global $result;
    $a++;
    if ($a < 10) {
        $result[] = $a;
        test($a, $result);
    }
    return $result;
}

 

3. 利用静态变量

static仅在第一次调用函数的时候对变量进行初始化,并且保留变量值。
function test($a = 0) {
    static $result = array();
    $a++;
    if ($a < 10) {
        $result[] = $a;
        test($a);
    }
    return $result;
}

 

三、PHP实现递归与无限分类的方法

$area = array(
    array('id'=>1,'area'=>'北京','pid'=>0),
    array('id'=>2,'area'=>'广西','pid'=>0),
    array('id'=>3,'area'=>'广东','pid'=>0),
    array('id'=>4,'area'=>'福建','pid'=>0),
    array('id'=>11,'area'=>'朝阳区','pid'=>1),
    array('id'=>12,'area'=>'海淀区','pid'=>1),
    array('id'=>21,'area'=>'南宁市','pid'=>2),
    array('id'=>45,'area'=>'福州市','pid'=>4),
    array('id'=>113,'area'=>'亚运村','pid'=>11),
    array('id'=>115,'area'=>'奥运村','pid'=>11),
    array('id'=>234,'area'=>'武鸣县','pid'=>21)
);
function t($arr,$pid=0,$lev=0){
    static $list = array();
    foreach($arr as $v){
        if($v['pid']==$pid){
            echo str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;",$lev).$v['area']."<br />";  //这里输出,是为了看效果
            $list[] = $v;
            t($arr,$v['id'],$lev+1);
        }
    }
    return $list;
}
 
$list = t($area);
echo "<hr >";
// print_r($list);

该程序执行后输出如下结果:

北京
    朝阳区
        亚运村
        奥运村
    海淀区
广西
    南宁市
        武鸣县
广东
福建
    福州市
posted @ 2019-02-25 23:56  鹿呦呦  阅读(369)  评论(2编辑  收藏  举报