现在的位置: 首页 > 综合 > 正文

浅识递归

2013年08月19日 ⁄ 综合 ⁄ 共 1143字 ⁄ 字号 评论关闭

 

递归:简单理解就是方法内部自身调用。
虽然递归的概念很简单,并且还可能出现耗尽系统资源的问题,但是,合理巧妙地使用递归,却可以解决一些使用常规方式很难解决的棘手问题。先通过个例子了解一下递归的应用:
假如要求出一个正整数n到1之间的所有数字累加的结果,可以在n-1到1之间的累加结果的基础上加上n,同理,要求出n-1到1之间的累积结果,可以在n-2到1的累加结果基础上再加上n-1,一次类推。。。,最后就成了要计算1到1之间所有数字的累加结果。
显然我们只要把n-1到1之间的结果搞定,那么就可以搞定n到1之间的结果。
假设要编写一个方法add,即这个方法可以完成正整数n到1之间的所有数字的累加结果,那么我们就可以调用这个add方法完成n-1到1之间的所有数字的累加结果,对应代码如下:
public int add(int n){
   return n+add(n-1);
}
上面add方法中的下一次递归调用的问题域很容易确定,就是n-1.当add方法逐层往下进行递归调用时,传递给add方法的参数逐步减小,最后就成了调用add(1),既要计算1到1之间所有数字的累加结果,很显然add(1)的结果就是1,我们不用继续进行递归调用就可以直接确定,所以,应选择当传递给add方法的参数为1的情况作为add递归方法的“递归头”,在这种情况下要终止递归调用,直接返回结果1即可。
所以代码如下:
public int add(int n){
 if(n==1){
   return 1;
 }else{
   return n+add(n-1);
 }
}
可以简化为:
public int add(int n){
  return (n==1)?1:(n+add(n-1));
}

设计递归方法时,通常要抓住如下三个要点:
(1)在编写递归方法的同时就假设这个方法已经可以被调用了,并且要调用这个方法自己去解决从当前大问题中抽取出来的同一种性质的更小的问题。写递归方法时,不要关心和琢磨抽取出来的较小的问题是具体如何处理的细节和过程,而是认为当前正在编写的递归方法正好就处理这个问题。
(2)在递归方法内部调用自己时,需要计算出传递给这次调用的参数,也就是要计算出下一次递归调用所要解决的问题域。
(3)在一定的条件下必须要终止继续向下进行递归调用,使得子方法调用能够一级级返回到主方法,这个终止递归调用的条件叫做“递归头”。每个递归方法都必须有个“递归头”,即必须限定一个递归结束条件来终止继续向下进行递归调用,否则,这个递归方法运行时必然会出现错误。另外,对于一个递归方法,即使在其中设定了“递归头”,程序运行时仍有可能用尽系统资源,所以,对于一个递归方法,还应该人为限制递归调用的次数,不能让递归次数过大。

 

本文为听了张孝祥老师的网络课堂后所做的记录。

抱歉!评论已关闭.