码迷,mamicode.com
首页 > 其他好文 > 详细

递归(recursion)

时间:2014-10-04 01:41:35      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:编程导论   java   递归      

人分两种:男人和女人;算法分两种:递归的和迭代/循环的;递归是指用自己的较简单的情形定义自己

在数学和计算机科学中,递归是一种思路和策略,可以用于术语的定义(什么是表达式)问题的描述问题求解。用于问题求解的递归称为递归法

有一个故事。物理学家计算10!时会说,“看,它等于1*2*~*10,即3628800”;数学家则说:“哦,10的阶乘,它等于10乘以9!”。

递归算法“轻率地”认为自己的较简单的情形是已知的。既然fact(n-1)是已知的,因而fact(n) 可求。这样“轻率”对理解递归概念至关重要。递归法不直接解决问题,而是将问题变成一个趋向递归出口的问题。使用递归方法需要存在一个基准情形,以避免无限循环(狗追自己的尾巴)。

bubuko.com,布布扣

package algorithm.recursion;
public class RecursionDemo{    
    /**
     * 递归求Fibonacci级数的第n个元素,n基于1的自然数。
     */
    public static int fibonacc(int n){
        if(n<=1) return n;
        else return fibonacc(n-1)+fibonacc(n-2);
    }
    
    /**
     * 迭代求Fibonacci级数的第n个元素,n基于1的自然数。
     */
    public static int fibonacc1(int n){
        int first , second ,result ;
        first =second=result= 1;
        for(int i=3;i<=n ;i++){
            result = first + second;
            first = second;
            second =result;
        }
        return result;
    }    
}
大多数情况下,迭代法和递归法能够相互转化。

使用递归法有2条实践准则:

1、设计优先。在任何情况下都可以采用递归法,简洁而清晰的程序设计优先。某些问题,例如那些需要后退的问题(如找出迷宫的出路、对树的一些操作),如果不采用递归则很难解决。

2、效率平衡。如果递归调用中出现重复性工作,改用循环。对于一般的数值计算,递归法通常不合适。

Java递归方法是通过方法调用栈实现的。在BlueJ中设置断点运行factorial (5),将显示方法调用情况。它仅仅“轻率地认为”factorial (4)已知,依此类推。到factorial (5),目前没有进行任一乘法计算。方法调用栈中有6个栈帧,顶层将计算factorial (0)。递归的方法的两个阶段是递推和回归

例如使用递归式sum(n) =n + sum(n-1),yqj2065看见过一个趣题。

    static long sum1(long a) {
        return (a == 1)? 1:(a + sum1(a - 1));
    }
    static long sum2(long a) {
        return (a == 1)? 1:(sum2(a - 1) + a);
    }
两者有区别吗?


汉诺塔

汉诺塔问题(Hanoi Tower problem):有三根杆子A、B、C,A杆上串有上小下大若干碟子。每次移动一块碟子,在确保小碟子只能叠在大碟子上面的条件下,利用B过渡,请把所有碟子从A杆移到C杆上。

对于具有递归思维的人,再多的碟子,也不过是两部分:上面的n-1个碟子被看成粘在一起的小碟子,而下面是一个大碟子。汉诺塔问题的递归算法:

结束条件: A杆上只有一个碟子,将它移到C。

递归式:

1、将上面的n-1个碟子从出发地A移到中转站B;

2、将第n个碟子移到目的地C;

3、将n-1个碟子从中转站B移到目的地C。

package algorithm.recursion;
public class HanoiTower{
    private static int step= 0;   
    /**汉诺塔的递归演示。
     * @param from  碟子的出发地
     * @param temp  碟子的中转站
     * @param to   碟子的到达地
     * @param n  要移动的碟子个数
     */
    static void  hanoi(char from, char temp, char to, int n){ 
        if (n == 1) {
           step++;
           System.out.println("第"+step+ "步: "+ from+"→"+ to);
        }else {
            //将n-1个碟子移到中转站,故目前的到达地是temp。
            hanoi(from, to,temp,n-1);
            //第n个碟子移到到达地
            step++;
            System.out.println("第"+step+ "步: "+ from+"→"+ to);
            //将n-1个碟子移到到达地。
            hanoi(temp,from,to,n-1);
        }
    }
}
hanoi(‘A’, ‘B’, ‘C’, 3)的输出:

第1步: A→C
第2步: A→B
第3步: C→B
第4步: A→C
第5步: B→A
第6步: B→C
第7步: A→C

汉诺塔问题的迭代算法比较复杂,

递归(recursion)

标签:编程导论   java   递归      

原文地址:http://blog.csdn.net/yqj2065/article/details/39762031

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!