簡體   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