繁体   English   中英

了解递归调用循环的工作方式

[英]Understanding how a loop of recursive calls work

我真的对恢复性很陌生,偶然发现了一个练习,在这个练习中,我们有一个循环进行多次递归调用,但我不明白它是如何工作的。

看下面的例子:

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

提前致谢 !

首先,您的示例代码将无限循环使用,因为在您的所有递归调用中if( n>100 )都会被评估为TRUE,因为您的“ n”值始终会增加。 calculateSomething(n+1)

如果您调用calculateSomething(200) ,则第一个递归调用将在for循环内,且i=0CalclulateSomething(201)

然后忘了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);
    }

即使返回类型为int,您所给的程序也没有return语句。 而且,由于没有结束条件,它将无限进行。

这将是执行周期

通话1:n = 200,i = 0计算方法(201次)

通话2:n = 201,i = 0calculateSomething(202)

通话3:n = 202,i = 0calculateSomething(203)...。

每个呼叫是否都将“ i”提高到10? 还是调用每个“ i”值?

调用i的每个值。 递归适用于堆栈(后进先出)。 在简单的程序中,我从main调用Method1并从Method1调用Method2,看起来像这样的堆栈

方法2

方法1

主要

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

由于您是新手,因此从一个简单的示例(例如阶乘)开始

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 *阶乘(1-1)

2 *阶乘(2-1)

3 *阶乘(3-1)

factorial(3)->实际方法调用

现在,每次调用返回此处,它将用实际值替换其下面的一个因子(n-1),即

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

阶乘(2-1)将替换为1 * 1

阶乘(3-1)将替换为2 *(1 * 1)

factorial(3)变为3 *(2 *(1 * 1))

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM