众所周知,几乎所有的算法都离不开递归和迭代,无论是从小白刚接触的冒泡排序,还是日后进阶的深度和广度搜索。
本文试就二者本质的区别与联系讨论开来,遗漏错误之处,烦请指出。
首先,从一输出到十,最先想到的肯定是:
for($i=1;$i<=10;$i++){
echo $i;
}
换成递归,则是:
function dg($n=10,$i=1){
if($i>$n){
return;
}
echo $i;
dg($n,++$i);
}
可以看到,递归把for里的三要素分别拆开了——这样看来,似乎迭代显得更加紧凑一些。
如果我们要两层for呢——连续输出10次1到10。
迭代的代码仍然十分简单:
for($j=1;$j<=10;$j++){
for($i=1;$i<=10;$i++){
echo $i;
}
}
可以看到,只要在外面多加一层即可——注意把$i换成$j。
递归的代码长这样:
function dg($n,$i=1,$j=1){
if($j>$n){
return;
}
if($i>$n){
dg($n,$i=1,++$j);
}
echo $i;
dg($n,++$i,$j);
}
dg(10);
注意到,从这里开始,对刚刚接触编程的小白来说,就开始有点理解的难度了——精彩的部分,也即将从这里开始。
多了一个if判断——这还比较好理解——可以理解为有两层for,所以需要两个判断。新手比较容易犯错的地方,是两个++要分开来写。
以此类推,有几层for,就写几个if判断,然后再注意每个++分开写——好像也没什么难的嘛!是的,恭喜你们已经从小白跻身为高手了!——想得美!好戏才刚刚要开始呢!
前面说到,有几层for就写几个if——那如果有100层,是不是就要写100个了!理论上来讲,我们可以这么做——似乎除了这么做,现在的我们也没有其它的办法了。
编程是需要哲学的。
人活在这个世界上,其实最讲究的是结合——只有和自己最心爱的女人结合,才能达到生命的大和谐!因此,只有将迭代和递归也结合起来,才能达到编程的大和谐!
具体要怎么做呢?
function dg($n=0,$i=1){
if($n==2){
echo $i;
return $n--;
}
for($i=1;$i<=10;$i++){
dg($n+1,$i);
}
}
可以看到,由$n控制层数,代码的可读性和质量,立即上升了几个层次。
如果要每层都输出
for($j=1;$j<=10;$j++){
echo $j;
for($i=1;$i<=10;$i++){
echo $i;
}
}
则只要把递归函数里的if里的echo移到for里
function dg($n=0,$i=1){
if($n==2){
return $n--;
}
for($i=1;$i<=10;$i++){
echo $i;
dg($n+1,$i);
}
}
到这里,几乎便是我目前为止掌握的所有有关递归和迭代的知识了。最后,还有一种情况,就是for的个数不确定的情况——
注意,我在这里说的是个数,而不是层数。看下面代码
function quickSort($arr) {
//先判断是否需要继续进行
$length = count($arr);
if($length <= 1) {
return $arr;
}
//选择第一个元素作为基准
$base_num = $arr[0];
//遍历除了标尺外的所有元素,按照大小关系放入两个数组内
//初始化两个数组
$left_array = array(); //小于基准的
$right_array = array(); //大于基准的
for($i=1; $i<$length; $i++) {
if($base_num > $arr[$i]) {
//放入左边数组
$left_array[] = $arr[$i];
} else {
//放入右边
$right_array[] = $arr[$i];
}
}
//再分别对左边和右边的数组进行相同的排序处理方式递归调用这个函数
$left_array = quick_sort($left_array);
$right_array = quick_sort($right_array);
//合并
return array_merge($left_array, array($base_num), $right_array);
}
这是快速排序,具体需要几个for,取决于左右数组的分布情况——如果硬要改为纯迭代,将很是麻烦。
剩下我还不知道的,希望各位在下面不吝指出。