2013-08-16 260 views
0

我在我的c#asp.net程序中使用遞歸函數,它拋出「StackOverflow異常」。當我在IIS中運行我的程序時引發此異常。遞歸vs循環

如果我使用循環代替遞歸函數,它會拋出「StackOverflow異常」?

在這種情況下使用循環或遞歸是很好的做法嗎?

編輯:

分析問題後,我發現了異常而引起,因爲遞歸的水平超過1000它會導致棧溢出。

現在,我完全失去了將遞歸函數轉換爲迭代,因爲使用了多次遞歸。我在這裏張貼的示例代碼以供參考:

RecursiveFunction(Node n) { 
    //Some Code for local variables 
node.processed=true; 
if(n.up){ 
    //Create a sub node for node below the current one 
    if(!subnode.processed) 
    RecursiveFunction(subnode); 
} 
else{ 
    //Create a sub node for node above current one 
if(!subnode.processed) 
    RecursiveFunction(subnode); 
} 
return result; 
} 

注:以上示例代碼可能是一個無限循環,因爲我只是用它來提多遞歸使用,其實際執行不是一個無限循環。

在這種情況下,基本條件是,如果已經處理了一個節點,它將不會使用遞歸併直接返回結果。

我的問題是,如果使用多個遞歸,我怎樣才能用迭代來替換它。我搜索了一下,發現了很多關於用迭代或庫存替換遞歸的建議。但我沒有發現任何有關用迭代替換多次遞歸的問題。

+1

是的,通常是可以的,張貼代碼。 – weston

+0

對不起,我不能發佈代碼,我的疑問即使我將遞歸函數轉換爲循環,它是否會解決問題(StackOverflow異常)? – Anandaraj

+0

@Anandaraj可能 – Grundy

回答

1

您可以通過管理自己的堆棧將任何遞歸函數轉換爲非遞歸函數。像這樣的:

void NonRecursiveFunction(Node n) { 
    var stack = new Stack<Node>(); 
    stack.Push(n); 

    while(stack.Any()) { 
     node = stack.Pop(); 
     //Some Code for local variables 
     node.processed=true; 
     if(n.up){ 
      //Create a sub node for node below the current one 
      if(!subnode.processed) 
       stack.Push(subnode); 
     } else{ 
      //Create a sub node for node above current one 
      if(!subnode.processed) 
       stack.Push(subnode); 
     } 
    } 
    return result; 
} 
+0

感謝您的快速回復。我會嘗試你的建議。 – Anandaraj

1

好了,你只是想知道這是否會解決這個問題:

是的,你不會,如果你切換到一個循環得到StackOverflowException

當您調用某個方法時,它將被推入調用堆棧。從內部調用相同的方法構建了一個更大更大的堆棧。最終,當程序使用堆棧中所有可用內存時,可能會彈出StackOverflowException

在一個循環中,你不會越來越多地推動堆棧,所以你不會遇到這個問題。然而,它可能不那麼直接實現,否則我們永遠不會使用遞歸。

正如其他人所提到的,可能沒有什麼錯,在這種情況下使用遞歸,它只是你沒有停在anypoint遞歸。在這種情況下,相同的循環版本將永遠持續(但您不會得到StackOverflow!)

+0

感謝您的回答 – Anandaraj