PHP 递归函数
递归函数即自调用函数,在函数体内部直接或间接的自己调用自己,即函数的嵌套调用就是函数本身。通常
在此类型的函数体中会附加一个条件判断,以判断是否需要执行递归调用,并且在特定的条件下终止函数的递归
调用动作,把目前流程的主控权交回到上一层函数执行。
总结:
1.递归是一种函数调用自身的机制
2.递归必须要有边界条件,也就是递归出口(退出递归)
3.递归前进段和递归返回段,也就是最后得到的值
4.当边界条件(递归出口)不满足的时候,递归前进;当边界条件(递归出口)满足时,递归返回
下面我们看一个简单的递归示例:
<?php // 声明一个函数 用于递归测试 function test($n) { echo $n . " "; //在函数开始输出参数的值 if($n > 0) { //判断参数是否大于0 test($n - 1); //如果参数大于0则调用自己,并将参数减1后再次传入 }else{ //判断参数不大于0 echo "<------>"; } echo $n . " "; } 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
第 6 步:执行 test(5),echo 5,因为 5 > 0,执行 test(4),后面还有没来得及执行的 echo 5
第 7 步 :执行 test(4),echo 4,因为 4 > 0,执行 test(3),后面还有没来得及执行的 echo 4
第 8 步 :执行 test(3),echo 3,因为 3 > 0,执行 test(3),后面还有没来得及执行的 echo 3
第 9 步 :执行 test(2),echo 3,因为 2 > 0,执行 test(1),后面还有没来得及执行的 echo 2
第 10 步 :执行 test(1),echo 1,因为 1 > 0,执行 test(0),此时 0 > 0 不成立不再执行 test() 函数,而是
echo "<------>",并且执行后面的 echo 0,此时函数不再调用自己,开始将流程的主控权交回给上一层函数执行,
也就是开始执行刚刚 test() 函数没来得及输出的最后一个 echo,整个流程如下图所示:
在函数执行的第 1 到第 10 步,函数输出的是绿色部分,红色部分还没来得及输出就执行调用自己的操作,以此
类推,直到流程执行到不满足调用自己的条件,输出 "<------>",流程开始执行前面没来得及输出的部分
这就像我们玩游戏一样,打死一个怪物掉下一件宝物,但是此时还有其他怪物在等着被消灭,我们不得不消灭完
所有怪物之后在回来一个一个捡宝物
但是,可能又会有人问为什么在流程执行到不满足调用自己的条件后下一个输出的是 1,而不是 10呢?,如下示例:
<?php function one($num) { echo $num; two($num - 1); echo $num; } function two($num) { echo $num; three($num - 1); echo $num; } function three($num) { echo $num } one(3); ----------------------------- 输出结果: 32123
执行 one(3) 函数,echo 3,然后调用 two(2) 函数,注意此时还没 echo 3
执行 two(2),echo 2,然后调用 three(1) 函数,同样还没 echo 2
执行 three(1) ,echo 1,不再调用其他函数
three() 函数执行结束 echo 2,则 two() 函数也执行结束,echo 3,所以,最后的输出结果就是 3,2,1,2,3