首先我们说说什么是递归。
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
这是百度百科所给出的解释。可见直白来说递归的意思就是调用自身的一种算法。而递归算法所包必有内容有3个:
1.边界条件:没有边界的递归想来大家知道是什么后果了,无限递归。就陷入死循环当中了,所以当我们使用递归是切记不要忘了判断边界。当我们递归陷入死循环首先也应该检查边界条件的逻辑是否有错误(这个笔者深有体会,被摆了好多次道)。
2递归前进段:也就是递归主主体,如何让递归深入的递归下去,这个就不需要多加解释了吧。
3.递归返回:这个就是我们需要递归做的事情,返回我们所需要的数据处理。
牢记这3个要点,写递归算法是就能大大减少错误了。
下面给出一个常见例子。跳台阶问题
* 跳台阶问题:两种上台阶方式
* 1.一次上一个台阶,
* 2一次上两个台阶,
* 问:登上n阶台阶共有多少种方式
思路:登上n阶台阶问题可以转换成登上n-2个台阶方式和登上n-1个台阶方式之和的问题
即有公式 f(n)=f(n-1)+f(n-2) (n>2)
f(1)=1;
f(2)=2;
使用上面的递归思想结合公式很容易写出程序。
那么我们再来看看跳台阶升级版的问题。
*跳台阶升级版,
* 跳台阶有n中方式
* 1.一次跳一个
* 2.一次跳两个
* 。。。。
* n.一次跳n个
* 问n个台阶共有多少种方式
与上面跳台阶不同的是这次跳台阶的方式变得多了起来,并且随着台阶数,方式不断增加,
然而解决思想并没有改变
思路:登上n阶台阶问题可以转换成登上n-2个台阶方式加上登上n-1个台阶加上登上n-3个台阶….加到登上1个台阶方式之和再加上一次登上总台阶和的问题
即有公式 f(n)=f(n-1)+f(n-2) +f(n-3)+……+f(3)+f(2)+(1)+1
下面给出这两个问题代码
<?php
/*
* 跳台阶问题:两种上台阶方式
* 1.一次上一个台阶,
* 2一次上两个台阶,
* 问:登上n阶台阶共有多少种方式
*
*/
function jump($num){
//递归求解时间复杂度为O(2n方);
while($num>2){
return $count=jump($num-1)+jump($num-2);
}
if($num==2||$num==1){
return $num;
}
}
function jump1($num){
//时间复杂度为O(n)
if($num==2||$num==1){
return $num;
}
$count=2;
$pre=1;
for($i=3;$i<=$num;$i++){
$tmp=$count;
$count=$count+$pre;
$pre=$tmp;
}
return $count;
}
/*跳台阶升级版,
* 跳台阶有n中方式
* 1.一次跳一个
* 2.一次跳两个
* 。。。。
* n.一次跳n个
* 问n个台阶共有多少种方式
*/
function jumpup($num){
/*还是递归问题
*
* 即;
* f(1)=1;
* f(2)=f(1)+1;
* f(3)=f(1)+f(2)+1;
* 故。
* f(n)=f(n-2)+f(n-1)+f(n-3)...+f(1)+f(2)+f(3);
* 由此见递归算法时间复杂度为O(n2)
*/
$count=0;
for($i=1;$i<$num;$i++){
$count=jumpup($num-$i)+$count;
}
return $count+1;
}
//echo jump(6);
//echo jump1(6);
echo jumpup(5);