了解递归调用循环如何工作

时间:2015-10-27 10:01:20

标签: loops for-loop recursion

我真的很不情愿,我偶然发现了一个练习,我们有一个循环进行几次递归调用,我不明白,它是如何工作的。

请看下面的示例:

int calculateSomething (int n) {

 if (n > 100)
  for (int i = 0; i < 10; i++)
   calculateSomething(n+1);
}

假设我第一次调用calculateSomething(200),我将要拨打多少电话?乍一看我会说100 * 10,所以1000个电话?

每次通话“i”都会一路走到10吗?或者它会调用“i”的每个值?

我很抱歉提出这样的问题,但我确实阻止了XD

提前致谢!

2 个答案:

答案 0 :(得分:2)

首先,您的示例代码将在无限循环中提供,if( n>100 )将在所有递归调用中被视为TRUE,因为您的&#34; n&#34;价值总是增加。 calculateSomething(n+1)

如果您致电calculateSomething(200),第一次递归调用将位于for i=0CalclulateSomething(201)

的for循环中

然后忘记for循环的下一次迭代,直到递归调用结束,正如我之前解释的那样,它永远不会发生。

calculateSomething(200)
  -> i=0 calculateSomething(201)
    -> i=0 calculateSomething(202)
      -> i=0 calculateSomething(203)
        -> ...infinite...

以下一个代码为例: (修正了无限循环,并减少了解释的值)

int calculateSomething (int n) {

 if (n < 3)
  for (int i = 0; i < 3; i++)
   calculateSomething(n+1);
}

递归调用将是:

calculateSomething(0)
  -> i=0 calculateSomething(1)

    -> i=0 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=1 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=2 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

  -> i=1 calculateSomething(1)

     -> i=0 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=1 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=2 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

   -> i=2 calculateSomething(1)

     -> i=0 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=1 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

     -> i=2 calculateSomething(2)

       -> i=0 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=1 calculateSomething(3)
         -> end. if (n < 3) = FALSE
       -> i=2 calculateSomething(3)
         -> end. if (n < 3) = FALSE

如果你想计算你的函数被调用的次数,你可以简单地添加一个conunter并为每次调用递增它,例如:

int counter = 0;  // declaring it on a global scope

int calculateSomething (int n) {

    counter++;

    if (n < 3)
      for (int i = 0; i < 3; i++)
       calculateSomething(n+1);
    }

答案 1 :(得分:2)

即使返回类型为int,您给出的程序也没有return语句。此外,它将继续无限,因为没有最终条件。

这将是执行周期

调用1:n = 200 i = 0 calculateSomething(201)

调用2:n = 201 i = 0 calculateSomething(202)

调用3:n = 202 i = 0 calculateSomething(203)....

&#34; i&#34;每次通话都要10路?或者它会调用&#34; i&#34;的每个值。 ?

调用i的每个值。递归适用于堆栈(Last in First out)。在简单的程序中说我从main调用Method1,从Method1调用Method2,这个堆栈看起来像这样

方法2

方法1

基本上,最后一个调用将位于顶部,一旦完成,它将转到下一个。

由于您刚开始使用像factorial

这样的简单示例
public static int factorial(int n) {
    if (n == 0) {
        return 1;
    } else {
        System.out.println(n + " "+ (n-1));
        return n * factorial(n - 1);
    }
}

如果你调用factorial(3),那么堆栈看起来像

1(因为阶乘(1-1),即阶乘(0)为0)

1 * factorial(1-1)

2 * factorial(2-1)

3 * factorial(3-1)

factorial(3)---&gt;实际的方法调用

现在,每次呼叫返回时,它都会将其下方的阶乘(n-1)替换为实际值,即

阶乘(1-1)将被1替换

阶乘(2-1)将被1 * 1

取代

阶乘(3-1)将被2 *(1 * 1)

取代

阶乘(3)变为3 *(2 *(1 * 1))

希望这有帮助。