簡體   English   中英

多次遞歸調用

[英]Multiple recursive calls

我知道什么是遞歸函數,以及如何可視化堆棧頂部的每個遞歸調用。 但我不知道當函數多次調用自身時如何思考

float foo(int n){

   int a = 0;
   for(int i = 0; i < n; i++)
       a += 1;

   if (n > 2)
       return foo(n/2) + foo(n/2); // What happens here?

    return a;
}

我現在應該考慮兩個不同的堆棧還是可視化結果的最佳方法是什么?

正如其他答案所提到的,只有一個堆棧和遞歸調用嚴格按照給定的順序進行評估。

但是,出於分析目的,您可以將整個調用序列可視化為一棵樹。 <code>foo(n)</code> 的調用樹

return foo(n/2) + foo(n/2); // What happens here?

第一個表達式在第二個評估之前完全評估。 與兩個不同的堆棧無關。 第一個調用的堆棧在計算時擴展和收縮,一旦這個表達式被完全計算,第二個開始。

這有助於形象化嗎?

我現在應該考慮兩個不同的堆棧還是可視化結果的最佳方法是什么?

它仍然是一個堆棧。 在這一行:

   return foo(n/2) + foo(n/2); // What happens here?

... 對 foo() 的第一個調用將被評估(將其參數和局部變量壓入堆棧,使用,然后再次從堆棧中彈出),然后另一個將在同樣的方法。 (請注意,語言規范中未定義首先評估哪個 foo() 調用,因此由編譯器的實現者決定他們喜歡的順序)。

讓我們嘗試可視化調用 foo(4) 的不同階段的堆棧(是的,只有一個堆棧):

在調用 foo(4) 之前:調用者堆棧

在原始調用 foo(4) 中:stack= caller-stack, foo(4)

當 foo(4) 在第一次調用 foo(2) 時:調用者堆棧,foo(4),foo(2)

foo(4) 在第一次調用 foo(2) 中,其中 foo(2) 已經調用了第一個 foo(1): caller-stack, foo(4), foo(2), foo(1)

從第一個 foo(1) 返回后:再次調用堆棧,foo(4),foo(2)

第一次調用 foo(2) 中的 foo(4),其中 foo(2) 調用了第二個 foo(1): caller-stack, foo(4), foo(2), foo(1)

從第二個 foo(1) 返回后:再次調用堆棧,foo(4),foo(2)

從第一個 foo(2) 返回后: caller-stack, foo(4)

foo(4) 在對 foo(2) 的第二次調用中: caller-stack, foo(4), foo(2)

foo(4) 在第二次調用 foo(2) 中,其中 foo(2) 已經調用了第一個 foo(1): caller-stack, foo(4), foo(2), foo(1)

從第一個 foo(1) 返回后:再次調用堆棧,foo(4),foo(2)

foo(4) 在第二次調用 foo(2) 中,其中 foo(2) 調用了第二個 foo(1): caller-stack, foo(4), foo(2), foo(1)

從第二個 foo(1) 返回后:再次調用堆棧,foo(4),foo(2)

從第二個 foo(2) 返回后: caller-stack, foo(4)

從 foo(4) 返回后:調用者堆棧

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM