递归算法
基本思想:
递归算法一般用于将较为复杂的规模较大的问题分解成规模较小的同类问题,通过函数或子过程直接或间接调用自身,以小规模问题解决复杂问题,使复杂问题简单化,使程序更加简洁,是解决很多计算问题的常用方法。递归算法程序代码简单,难点主要在递归模型的构建,即递归参数的寻找、递归出口的设计以及递归函数的调用等。由于递归函数的调用是通过栈空间实现的,过深的递归调用和不当的递归出口都容易造成栈溢出和超时问题,使用时需注意。下面以第39级台阶为例体会递归的运用:
第39级台阶:
题目描述:
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?
输出格式:
输出一个整数
程序分析:
首先找到问题的核心,将无用的条件抛掉,该题目可以简化为:共走偶数步,每次只走1或2个台阶,总共走39级台阶,求有几种走法。本问题可构建一个类似于二叉树的模型,每一步都分两种情况,走1个或2个。由题目限制条件容易看出走至第39个台阶时,只能有从第37级台阶走了2个台阶或从第38级台阶走了1个台阶这两种走法,则到第39台阶的走法=到第37级走法+到第38走法,以此类推……
程序设计:
因为本题共两个限制条件,在此处中我将递归参数设为剩余台阶数和已经走过的步数,可根据需要设为其他的参数。
public class TaiJie {
/* n——剩余台阶数
* x——走的步数
*/
static int f(int n,int x){
//递归出口
if(n==1){
if(x%2==0)return 0;
return 1;
}
if(n==2)return 1;
return f(n-1,x+1)+f(n-2,x+1);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(f(39,0));
}
}
根据程序分析可将递归调用方式设为:
return f(n-1,x+1)+f(n-2,x+1);
参数的出口设置需注意避免栈溢出,当n=3时,若直接return上式,则栈中需要有参数n=2和n=1的情况,若没有则溢出,同理,当n=2时栈中需要有n=1和n=0的情况所以为防止出现栈溢出。因此不妨就将n=1和n=2设为出口。设置出口时就要考虑本题的另一个限制条件总步数为偶数步,当n=2时容易看出无论当前已经走了奇数步或者偶数步,剩余的两步都有且只有一种解法,所以可以直接将n=2时赋值为2;当n=1时则要分两种情况考虑,若已经走了奇数步,则有满足条件的1个解,return 1,若已经走了偶数步说明此种走法不合题意,return 0。