在递归语句中,java如何存储过去的值?

时间:2016-03-23 21:04:17

标签: java recursion

public class Factorial {
int factR(int n){
    int result;
    if(n==1)return 1;
    result=factR(n-1)*n;
    System.out.println("Recursion"+result);
    return result;
}

我知道这个方法会有

的输出
  Recursion2
  Recursion6
  Recursion24
  Recursion120
  Recursive120

但是,我的问题是java如何存储阶乘的过去值?看起来好像java决定将自下而上的值相乘。这种情况发生的过程是什么?它是由于java如何在其堆栈中存储内存?

3 个答案:

答案 0 :(得分:3)

http://www.programmerinterview.com/index.php/recursion/explanation-of-recursion/

值存储在Java的调用堆栈中。由于定义了这种递归函数,它是相反的。你得到n,然后将它乘以n-1的相同函数的值,依此类推,依此类推,直到达到1并在该级别返回1。因此,对于5,它将是5 * 4 * 3 * 2 * 1.无论乘法的方向如何,答案都是相同的。

你可以通过编写一个破坏堆栈并给你一个StackOverflowError的程序来看看它是如何工作的。你不能在调用堆栈上存储无限状态!

public class StackTest {
    public static void main(String[] args) {
        run(1);
    }

    private static void run(int index) {
        System.out.println("Index: " + index);
        run(++index);
    }
 }

答案 1 :(得分:1)

它实际上并不存储过去的价值观。一点都不它将程序的状态存储在堆栈中,每个方法调用的框架包含数据,例如程序所在的当前行。但是对于堆栈顶部的当前方法,变量result在任何时候只有一个值。返回并用于在调用此框架的框架中计算result,依此类推,从而显示自下而上的行为。

使这种不那么混乱的一种方法是暂时从图片中取出递归。假设Java不支持递归,并且只允许方法调用其他不同的方法。如果您仍想采用类似的方法,一种粗略的方法是将factR方法复制粘贴到多个不同但相似的方法中,例如:

int fact1(int n){
    int result;
    if(n==1)return 1;

    // Here's the difference: call the 'next' method
    result=fact2(n-1)*n;

    System.out.println("Recursion"+result);
    return result;
}

同样定义调用fact2等的fact3,尽管最终你必须停止定义新方法,并希望最后一个方法不被调用。这将是一个可怕的计划,但它应该是非常明显的,它是如何工作的,因为没有什么神奇的。有些人认为你可以意识到factR基本上是在做同样的事情。然后你可以看到Java没有决定'从底部向上乘以值:观察到的行为是给定代码的唯一逻辑可能性。

答案 2 :(得分:0)

我正在努力了解你,

如果有人同样打电话

factR(3)它是递归过程,所以显然java使用Stack来维护工作流程,

  

注意:请逐步查看下面的程序任务,并再次注意   在当前任务完成后它回来的地方。

result=factR(2)*3 // again call where n=2
    -> result=factR(1)*2 // again call where n=1
            -> now n=1 so that it will return 1

    -> result=1*2 // after return it will become 6
       print "Recursion2" // print remaning stuff
       return 2;
result=2*3 // after return it will become 6
print "Recursion3" // print remaning stuff
return 3