黑马程序员技术交流社区

标题: 递归的方法不是太懂,有大神可以帮忙解释一下吗? [打印本页]

作者: 宋星    时间: 2014-1-19 18:08
标题: 递归的方法不是太懂,有大神可以帮忙解释一下吗?
我只知道递归这个东西可以用,但不知道怎样用,请帮忙举下例子,和相关的知识点

作者: 花生壳    时间: 2014-1-19 18:14
求阶乘 5!
可以使用递归调用的方式。
1.使用递归必须要有出口(结束条件)
2.递归就是在满足条件的时候调用自己

作者: wodenhaowzg    时间: 2014-1-19 18:19
递归:就是一个方法内部再一次调用自己,或循环调用自己
就比如你饿了,你想吃饭,但这里只有馒头
把"吃饭"这个功能比作一个可以吃饱的方法,你调用一次"吃饭"方法,该方法给你返回一个馒头,由于你吃一个馒头吃不饱,所以在"吃饭"的方法里再调用这个"吃饭"的方法,就能循环的给你馒头了,直到你吃饱
代码就是:
public void chifan()
{
          geiManTou();
          chifan();
}
作者: 宋星    时间: 2014-1-19 18:25
花生壳 发表于 2014-1-19 18:14
求阶乘 5!
可以使用递归调用的方式。
1.使用递归必须要有出口(结束条件)

谢谢,可以举一下例子吗
作者: 宋星    时间: 2014-1-19 18:27
wodenhaowzg 发表于 2014-1-19 18:19
递归:就是一个方法内部再一次调用自己,或循环调用自己
就比如你饿了,你想吃饭,但这里只有馒头
把"吃饭" ...

这会不会有问题啊,会不会是死循环啊?
作者: wodenhaowzg    时间: 2014-1-19 18:37
宋星 发表于 2014-1-19 18:27
这会不会有问题啊,会不会是死循环啊?

你说的正是递归要注意的事项:
1.限定条件,否则无限循环。
2.注意递归的次数,尽量避免内存溢出。因为每次调用自身函数,都会在栈内存中开辟一个空间。
视频里总结有
作者: HelloSummer    时间: 2014-1-19 20:28
递归简单点来说就是自己调用自己,一般是方法中调用了方法本身。而被调用的方法本身中又包含有方法本身,所以形成了每次对方法进行调用而触犯下一次调用的情况。总之个人感觉初学的时候来讲相当混乱。
这里简单举个例子,也是我之前遇到的最常见的使用递归的情况,说的不好的大神勿喷:
web应用程序中经常用到需要动态输出导航列表这种情况。而导航列表项的数据动态读取出来后,这里不考虑高级的面向对象的方式封装的话,一般就放在数组里面,导航列表如果只是一级的就简单了,对数组进行个循环输出就搞定。
但很多时候会用到下拉等多级导航列表这种情况。对于级数是可以确定的下拉列表来说,也比较简单,对循环进行嵌套即可,最多的级数有多少就嵌套几层即可。
但还有种典型情况就是无线分级的情况,在程序设计的时候无法预知到该树状结构的级数,这时候一般是会采用递归的方式。
一般这种问题的思路是,先对根节点进行遍历,遍历的时候判断是否是最终节点(也就是判断该节点有没有子节点),如果有,对该节点的子节点进行遍历,同样的在遍历的时候对每个节点是否有子节点进行判断,以此往复,如果没有子节点,则输出该节点。
将这种思路抽取为代码来写的话可以将对子节点进行遍历和判断抽取为一个函数。
将一个节点作为这个函数的参数,函数先判断这个节点是否有子节点,有的话在用该节点作为参数再次调用这个函数,如果没有的话,执行输出菜单的操作,进入下一项。
作者: 宋星    时间: 2014-1-19 20:40
HelloSummer 发表于 2014-1-19 20:28
递归简单点来说就是自己调用自己,一般是方法中调用了方法本身。而被调用的方法本身中又包含有方法本身,所 ...

谢谢,不过我还没学过web,你说的我不是太懂,还是感谢你。
作者: HelloSummer    时间: 2014-1-19 21:05
宋星 发表于 2014-1-19 20:40
谢谢,不过我还没学过web,你说的我不是太懂,还是感谢你。

其实递归最经典的应用就是在数据结构里面,树的遍历中,其实在数据结构中用的超广泛和灵活.有空看下数据结构你就清楚了.超巧妙,很有趣.不过数据结构的教程一般用C来做讲解的比较多,java讲数据结构的好像没怎么见到。我是来混技术分的,求入学~
作者: panzhenglian    时间: 2014-1-19 23:19
限定了条件,然后在方法内自己调用自己这个方法,就叫做递归,但是递归次数不能太多,否则会内存溢出

作者: 廉伟杰    时间: 2014-1-20 16:11
递归 可以通俗的理解为自己调用自己的意思
例子: 问题是阶乘函数的可定义为
f(0)=1             n=0   
f(n)=f(n-1)*n   n>=1
函数如下
int f (int n )
{
         return n = 0 ? 1 : f(n-1)*n;
}

其实做用到递归的题
可以把他的函数关系列出来,像上边的例子,得到f(n)和f(n-1)的关系,这样的化就能自身函数调用自身的函数,应该就是这个意思的

希望对你有所帮助,对我的回答有疑问的话,我会解答的
作者: 姬运涛    时间: 2014-1-20 20:37
所谓递归,是指程序调用自身,当然,递归不会无休止地调用下去,它必然有一个出口,当满足条件时程序也就结束了,不然的话,那就是死循环了。
看下面这个类,有几个递归方法,看了之后肯定会对你学习递归很有帮助的。
/**递归类Recursion的定义*/
public class Recursion{
      //递归方法DecimalToBinary,把一个十进制数转换成二进制数
      public static void DecimalToBinary(int num){
             if(num ==0){        //当num=0时,循环结束
                    return;
             }else{
                    DecimalToBinary(num/2);  //调用递归方法
                    System.out.print (num%2);
             }
             }
      
      //递归方法sum,求1+2+...+100 的求和
      public static int sum(int num){
             if(num > 0){
                    return num + sum(num-1); //调用递归方法
             }else{
                    return0;      //当num=0时,循环结束
             }
            
      }   
      
      //递归方法yueshu,求两个数的最大公约数   ,用两个数的绝对值与这两个数较小的那个一直比较,直到相等为止。               
      public static void yueshu(int num1,int num2){
             if(num1 == num2){
                    System.out.println(num1);  //num1=num2时,结束
             }
             else{
                    yueshu(abs(num1-num2),min(num1,num2)); //调用递归方法
             }
                                 
      }
      
      //求两个数绝对值
      public static int abs(int num){
             return num>0 ? num : -num;
      }
      
      
     //求两个数较小者                                    
      public static int min(int num1,int num2){
             return num1 > num2 ? num2 :num1;
      }
      
      //递归方法hanon,求瀚诺塔函数
      public static void hanon(int n,char a,char b,char c){
      if(n == 1){
                    move(1,a,c);//最后一种情况是,把A柱子上盘子移到C柱子上。
                    return;
             }
      hanon(n-1,a,c,b);  //递归,把n-1个盘子从A 盘上借助C盘移到B盘上
      move(n,a,c);//调用move()方法
      hanon(n-1,b,a,c);//递归,把把n-1个盘子从B盘上借助A盘移到C盘上
      }
      
      public static void move(int n,char a,char c){
                    System.out.println(n+":"+a+"-->"+c);//打印移动盘子情况
             }
            
            
      //主函数main
      public static void main(String [] args){
            
             yueshu(12,8);              //求最大公约数
             hanon(3,'A','B','C');      //求瀚诺算法
             System.out.println(sum(100));//求和
             DecimalToBinary(103);//十进制转换二进制
            
      }
      
}




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