java - 递归方法的调用顺序

标签 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

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

最佳答案

在 Java 中,语句是从左到右计算的。以下是较小输入上斐波那契函数的简单分割:

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。语句 (1) 最终完成计算 fibo("left", 2 ) 并且可以继续以与上面相同的方式评估 fibo("right",1)

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

关于java - 递归方法的调用顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10768990/

相关文章:

java - java中图片的颜色直方图 - 错误的结果

javascript - 暴力算法会导致堆栈溢出吗? (递归)

php - php Peg Puzzle 解算器超时

JavaScript 性能长时间运行的任务

java - 具有一对多关系和 java.util.Map 的 EclipseLink JAXB (MOXy)

java - 下载 CSV 格式的完整数据库

Java Applet 以蜗牛般的速度加载

php - 从数据库结果生成多维数组的递归函数

javascript - 请求内递归函数调用的异步问题

java - AndroidManifest.xml 使用 public.xml 中存储的整数 id 作为主题