递归方法调用的顺序

时间:2012-05-26 19:04:33

标签: java recursion

我很好奇jvm中的递归是如何工作的。按照例子。首先计算给定数的阶乘。

public class Factorial {

public int factorial(int n) {
    System.out.println("Factorial: " + n);
    if ( n < 2) {
        return 1;
    } 

    return n * factorial(n - 1);
}

执行以下测试

    @Test
public void test_factorial() {
    Factorial fact = new Factorial();
    System.out.println(fact.factorial(3));
}

显示器

3
2
1

而且很明显,方法调用放在堆栈中,执行达到n == 1然后又回来了。 现在,我试图计算斐波纳契数。

public int fibo(String name, int n) {
    System.out.println("fibo: " + name +  " " + n);
    if (n < 2 ) {
        return n;
    }
    return fibo ("left", n - 1) + fibo ("right", n - 2);
}

执行测试

@Test
public void test_fibonacci() {
    Fibo fibo = new Fibo();

    assertEquals(8, fibo.fibo("start",6));

}

打印以下内容

fibo: start 6
fibo: left 5
fibo: left 4
fibo: left 3
fibo: left 2
fibo: left 1
fibo: right 0
fibo: right 1
fibo: right 2
fibo: left 1
fibo: right 0
fibo: right 3
fibo: left 2
fibo: left 1
fibo: right 0
fibo: right 1
fibo: right 4
fibo: left 3
fibo: left 2
fibo: left 1
fibo: right 0
fibo: right 1
fibo: right 2
fibo: left 1
fibo: right 0

我的问题是在这个例子中调用方法并将其放入堆栈的规则是什么?

2 个答案:

答案 0 :(得分:3)

语句在Java中从左到右进行评估。以下是对较小输入的Fibonacci函数的简单细分:

fib.fibo("start",3)

被调用,打印“start:3”。它试图评估

(1) fibo("left", 2) + fibo("right", 1)

由于评估是LTR,这意味着

(2) fibo("left", 2)
首先评估

。我们创建一个新的堆栈框架,而语句(1)正在等待它的返回。调用(2)打印“left:2”并尝试评估

(3) fibo("left", 1) + fibo("right", 0)

同样,LTR评估意味着我们评估

(4) fibo("left", 1)

第一。同样,新的堆栈帧,(3)等待(4)的响应。调用(4)打印“left:1”并返回1.堆栈帧弹出,(3)现在继续其评估,调用

(5) fibo("right", 0)

打印“right:0”并返回0.(2)现在能够完成其评估并返回1 + 0 = 1. Statement(1)最终已完成对fibo("left", 2)的评估并可继续以与上述相同的方式评估fibo("right",1)

我希望这有助于澄清一些内容!

答案 1 :(得分:1)

有什么问题? 你在运行这段代码时左右移动(left1右边有2个):

             start
    left1           right1 
left2  right2    left3  right3 

先拨打left1,然后拨打left2。然后返回到left1,但不打印它,然后调用right2。然后返回两次,你再次进入start。之后,您拨打right1,这将是类似的。

所以你有: 开始 - 左1 - 左2 - 右2 - 右1 - 左3 - 右3