php递归算法

递归函数是咱们经常使用到的一类函数,最基本的特色是函数自身调用自身,但必须在调用自身前有条件判断,不然无限无限调用下去。实现递归函数能够采起什么方式呢?本文列出了三种基本方式。理解其原来须要必定的基础知识水品,包括对全局变量,引用,静态变量的理解,也需对他们的做用范围有所理解。递归函数也是解决无限级分类的一个很好地技巧。若是对无限级分类感兴趣,请参照php利用递归函数实现无限级分类。我习惯套用通俗的话解释复杂的道理,您确实不明白请参见手册。php

  利用引用作参数数组

  先无论引用作不作参数,必须先明白引用究竟是什么?引用不过是指两个不一样名的变量指向同一块存储地址。原本每一个变量有各自的存储地址,赋值删除各行其道。如今可好,两个变量共享一块存储地址。 $a=&$b; 。实际上指的是 $a 无论不顾本身原来的存储地址,非要和 $b 共享一室了。于是任何对存储地址数值的改变都会影响两个值。  函数

  函数之间原本也是各行其是,即使是同名函数。递归函数是考虑将引用做为参数,成为一个桥梁,造成两个函数间的数据共享。虽然两个函数见貌似操做的是不一样地址,可是实际上操做的是一起内存地址。spa

?.net

1code

2htm

3递归

4内存

5ci

6

7

8

9

10

function test($a=0,&$result=array()){

$a++;

if ($a<10) {

  $result[]=$a;

  test($a,$result);

}

echo $a;

return $result;

 

}

  上面的例子很是简答,以a<10做为判断条件,条件成立,则把a赋给result[];将result的引用传入函数,会将每一次递归产生的a添加到结果数组result。于是本例生成的$result数组是 Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 ) 。

本例比较有意思的是echo a的值。相信不少人认为是12345678910吧,其实否则,是1098765432。为何呢?由于函数还没执行echoa前就进行了下一次的函数递归。真正执行echo a是当a<10条件不知足的时候,echo a,返回result,对于上一层而言,执行完递归函数,开始执行本层的echo $a,依次类推。

  利用全局变量

  利用全局变量完成递归函数,请确保你确实理解什么是全局变量。global在函数内申明变量不过是外部变量的同名引用。变量的做用范围仍然在本函数范围内。改变这些变量的值,外部同名变量的值天然也改变了。但一旦用了&,同名变量再也不是同名引用。利用全局变量实现递归函数不必理解到这么深的一层,还保持原有对全局变量的见解就能够瓜熟蒂落理解递归函数。

?

1

2

3

4

5

6

7

8

9

function test($a=0,$result=array()){

  global $result;

  $a++;

  if ($a<10) {

    $result[]=$a;

    test($a,$result);

  }

  return $result;

}

  利用静态变量

  咱们经常在类中见到static,今天咱们把它利用到递归函数中。请记住static的做用:仅在第一次调用函数的时候对变量进行初始化,而且保留变量值。

  举个栗子:

?

1

2

3

4

5

6

7

8

9

10

11

function test(){

static $count=0;

echo $count;

 

$count++;

}

test();

test();

test();

test();

test();

  请问这一段代码的执行结果是多少?是00000么?必然不是。是01234。首先第一次调用test(),static对 $count 进行初始化,其后每一次执行完都会保留 $count 的值,再也不进行初始化,至关于直接忽略了 static $count=0; 这一句。

  于是将static应用到递归函数做用可想而知。在将须要做为递归函数间做为“桥梁"的变量利用static进行初始化,每一次递归都会保留"桥梁变量"的值。

?

1

2

3

4

5

6

7

8

9

function test($a=0){

  static $result=array();

  $a++;

  if ($a<10) {

    $result[]=$a;

    test($a);

  }

  return $result;

}

  总结

  所谓递归函数,重点是如何处理函数调用自身是如何保证所须要的结果得以在函数间合理"传递",固然也有不须要函数之间传值得递归函数,例如:

?

1

2

3

4

5

6

7

8

function test($a=0){

  $a++;

  if ($a<10) {

    echo $a;

 

    test($a);

  }

}

  面对这样的函数,咱们就没必要大伤脑筋了。顺便说一句,深刻理解变量引用相关知识对解决这类问题大有裨益。

最后给你们分享一个php实现递归与无限分类的方法,具体实现方法以下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<?php

echo "<pre>";

$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(" ",$lev).$v['area']."<br />";

//这里输出,是为了看效果

$list[] = $v;

t($arr,$v['id'],$lev+1);

}

}

return $list;

}

$list = t($area);

echo "<hr >";

print_r($list);

?>

相关文章
相关标签/搜索