黑马程序员技术交流社区

标题: 函数递归的问题 [打印本页]

作者: lipingan0520    时间: 2013-4-14 10:37
标题: 函数递归的问题
本帖最后由 lipingan0520 于 2013-4-14 15:43 编辑

怎么学好函数递归呢,大家有什么心得吗?谢谢分享下哦。
作者: 李志敏    时间: 2013-4-14 10:45
递归就是程序调用自身 然后无休止的循环下去 当满足某一条件时候 也就是的有一个出口 递归结束 例如
求1+2+...+100 的和
  1. public class Test {

  2.         /*
  3.          * 采用递归方法计算1++2+3+....+100; 如果num大于0则将num-1后继续执行此方法直至num=0,递归结束
  4.          */
  5.         public static int sum(int num) {
  6.                 if (num > 0) {
  7.                         return sum(num - 1) + num;
  8.                 } else {
  9.                         return num;
  10.                 }
  11.         }

  12.         public static void main(String args[]) {
  13.                 // 输出1++2+3+....+100的和
  14.                 System.out.println(sum(100));
  15.         }
  16. }
复制代码

作者: 段旭东    时间: 2013-4-14 10:49
想要学好 主要还是 练习了!熟悉那种感觉,也就是传说中的编程思想!做得多了 你就有感觉了 而且特别有意思,要是有同学就一起讨论 特别激情!
作者: ①人←①城市    时间: 2013-4-14 10:57
递归  递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现像.
  程序调用自身的编程技巧称为递归( recursion)。
  一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。
  一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
  注意:
  (1) 递归就是在过程或函数里调用自身;
  (2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
  递归算法一般用于解决三类问题:
  (1)数据的定义是按递归定义的。(Fibonacci函数)
  (2)问题解法按递归算法实现。(回溯)
  (3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)
  递归的缺点:
  递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等
作者: 陈圳    时间: 2013-4-14 10:58
先学算法,再玩递归,不要只学一个单方面.而且递归,用不好是灾难.用得好才是效率.
二楼的递归代码,只是一个示例.这种用for循环做更容易理解,而且效率还高.

作者: 陈圳    时间: 2013-4-14 11:00
  1. 给你我总结的一点东西.
  2. 递归的内存消耗
  3.                 当于递归算法,递归的使用只能限于精简算法,否则递归的效率会奇低.
  4.         ----------------------------------------------------------------
  5.         示例:                                                        论坛找的例子.
  6.         public class PruduceCattle {

  7.         /** 一个农夫养了一头牛,三年后,这头牛每一年会生出1头牛,生出来的牛三年后,又可以每年生出一头牛……
  8.          * 问农夫10年后有多少头牛?n年呢?(不考虑其他因素,只考虑此数学问题)
  9.          * 规律:即f(n)=f(n-2)+f(n-3)+f(n-4)(n > 4);这个用递归效率奇低.
  10.          * 我找的规律:f(n)=f(n-1)+f(n-3);(n>3)
  11.          * @param args
  12.          */
  13.         public static void main(String[] args) {
  14.                 // TODO Auto-generated method stub
  15.                 Long begin=System.currentTimeMillis();
  16.                 System.out.println(getCattleCount(1000));
  17.                 System.out.println(System.currentTimeMillis()-begin+"毫秒");
  18.                 //我的算法时间:
  19.                 /*50          1000
  20.                 83316385      4.239507006748923E165
  21.                 0毫秒                    31毫秒*/        
  22.                 /*Long begin=System.currentTimeMillis();
  23.                 System.out.println(getSum(50));
  24.                 System.out.println(System.currentTimeMillis()-begin+"毫秒");*/
  25.                 //递归算法的时间:
  26.                 /*50          1000
  27.                         565毫秒     超过5分钟,我等了很久没出结果
  28.                 */
  29.         }
  30.         public static int getSum(int years) {//他人的示例
  31.                 if (years == 0)
  32.                         return 0;
  33.                 else if (years >= 1 && years <= 3)
  34.                         return 1;
  35.                 else if (years > 3)
  36.                         return getSum(years - 2) + getSum(years - 3) + getSum(years - 4);//这里相当于一个三层嵌套for循环
  37.                 else
  38.                         System.out.println("输入有误,请重新输入!");
  39.                 return years;
  40.         }
  41.         public static double getCattleCount(int n){
  42.                 double sum=0;
  43.                 double first=1;
  44.                 double second=1;
  45.                 double thread=1;
  46.                 for(int i=0;i<n-3;i++){//这是一个线性算法,程序算法,只循环n-3次.
  47.                         sum=first+thread;
  48.                         first=second;
  49.                         second=thread;
  50.                         thread=sum;
  51.                 }
  52.                 if(n<=3)
  53.                         return 1;
  54.                 else return sum;
  55.         }
  56. }
复制代码
  1. 关于递归的使用
  2.         1:使用递归,必须是带着能减少循环次数的目的去递归的.否则就会适得其反.看似代码简单.却会造成程序内存崩溃.
  3.         2:如果递归的次数过多,就避免使用递归求解,或者优化递归次数.
  4.         关于递归的高效使用:
  5.         //求一个数的任一次方
  6.                 public static long pow(int x,int n){
  7.                 if(n==0)
  8.                         return 1;
  9.                 if(n%2==0)
  10.                         return pow(x*x,n/2);//n是递归次数.n/2次递归就代表程序运行次数会少于n/2
  11.                         else  return pow(x*x,n/2)*x;
  12.         }
  13.         /*如:pow(2,64)求2的64次方:运算次数为:64->32->16->8->4->2->1->0  共8次求解
  14.         而pow(2,1200)运算次数为:1200-600-300-150-75-37-18-9-4-2-1-0     共12次求解
复制代码

作者: 刘胜寒    时间: 2013-4-14 11:06
李志敏 发表于 2013-4-14 10:45
递归就是程序调用自身 然后无休止的循环下去 当满足某一条件时候 也就是的有一个出口 递归结束 例如
求1+2+ ...

记忆化懂不懂...可以很大程度上优化你的代码执行效率
作者: 黄玉昆    时间: 2013-4-14 14:07
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
作者: lipingan0520    时间: 2013-4-14 15:46
谢谢各位的回答,和版主的加分。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2