2012-09-14 61 views
3

什麼是檢索遞歸調用函數的順序的最簡單的方法函數的階數。例如,如果我們有一個遞歸函數,它會一直調用自己,直到找到基本大小寫,然後一次返回一個函數。返回的第一個函數的順序爲0,第二個函數的順序爲1,依此類推...檢索訂單信息的簡單方法是什麼?比如說,當它是三號函數的時候,我想做一些特別的事情。獲得了遞歸調用

編輯:我希望堆棧頂部的函數爲零。

Edit2:我試圖解決的問題是返回第二個元素的順序遍歷二叉樹。

+0

聽起來有趣,你能提供更多的細節和/或代碼嗎? – Pao

+0

您可以使用參數傳遞您爲每次調用增加的參數,或者只是迭代地完成整個事件。這聽起來像你想要遞歸樹中每個節點的深度。 – oldrinb

+0

要在遍歷樹中查找'nnth'元素,請將計數器*傳遞給*和*以便從每次遞歸調用中取出。兄弟姐妹得到了從前面的兄弟姐妹穿過而來的計數器。 – 2012-09-14 22:44:43

回答

5

如果你開始用遞歸函數看起來像這樣

void recursive(int p1, String p2, long p3) { 
    ... 
    if (someCondition) { 
     recursive(nextP1, nextP2, nextP3); 
    } 
} 

它改成這樣:

void recursive(int p1, String p2, long p3, int level) { 
    ... 
    if (someCondition) { 
     recursive(nextP1, nextP2, nextP3, level+1); 
    } 
} 

現在通過調用

recursive(initialP1, initialP2, initialP3, 0); 
開始關閉在零水平

level將指示調用recursive的次數在你上面。

編輯:(零在最頂部)

您也可以將函數返回其水平實行「頂部零」的策略:

int recursive(int p1, String p2, long p3) { 
    if (baseCase) { 
     return 0; 
    } 
    ... 
    int level = 0; 
    if (someCondition) { 
     level = 1+recursive(nextP1, nextP2, nextP3); 
    } 
    return level; 
} 

注在這種情況下,直到最後一次遞歸調用返回後才能找到level

+0

要添加到此,您可能需要保留原始遞歸函數,然後使用額外參數調用新遞歸函數。這樣調用者(例如'main()')就不知道區別。 –

+0

有趣的是,如果我想讓最深的函數(堆棧頂部的函數)爲零,該怎麼辦? – Keeto

+0

@Keeto在下一次調用返回之前(因爲您不知道它們中會有多少人),您無法知道自己的級別是否爲「頂部零」。你可以從之前的調用中返回關卡,並添加一個來學習你的關卡,但是你可以只在「事實之後」這樣做。 – dasblinkenlight

0
  • 如果0級應該是最後的「嵌套調用」,那麼它是在普通 不可判定的問題類似停機問題,因爲你不能 只是說「後3次嵌套調用時,函數將返回一個 值「。只有通過模擬特定函數的計算,纔有可能展望未來。

  • 如果0級應該是第一次調用,那麼它非常簡單,您可以使用該級別作爲方法的參數並將其增加。

順便說一句,有趣的問題,請參見http://en.wikipedia.org/wiki/Halting_problem

3

的情況下dasblink已經給了你佔地面積你的建議實施明智的,因爲電平計數器,當您去的遞歸更深的上升(增量)相反。

如果您希望在遞歸更深的時候減少它,這意味着您事先知道確切的遞歸深度。

在大多數情況下,如果您知道確切的遞歸深度,您將不會使用遞歸,您將使用循環(for,while,repeat/until等)。事實上,在這種情況下使用遞歸是不太理想的,因爲分配的遞歸棧(更高的內存消耗)和循環效率更高。

+0

+1「在大多數情況下,如果你知道確切的遞歸深度,你將不會使用遞歸」這是一個完美的觀察! – dasblinkenlight

+0

大多數情況下,它使用遞歸函數的語法更清晰。如果這段代碼需要可重用,那麼無論如何你都會編寫一個函數,所以大多數人(包括我自己)有時候應該是鋸齒形的。 –

+1

使用遞歸函數可以很容易地結束堆棧溢出。您可以通過-s Stacksize或-oss Stacksize來增加堆棧。但是,每個方法調用都意味着開銷,如果遞歸預計會很深,那麼這是我們應該避免的。 –