從遞歸到迭代的方法在我多年的編程中,我經常使用遞歸來解決簡單的問題,但我完全意識到,有時由于內存/速度問題,您需要迭代。所以,在很久以前的某個時候,我試著去尋找是否存在任何“模式”或教科書方法來將一種常見的遞歸方法轉換為迭代,卻一無所獲?;蛘咧辽傥矣洃浿械娜魏螙|西都不會有幫助。有一般規則嗎?有“模式”嗎?
3 回答

慕娘9325324
TA貢獻1783條經驗 獲得超4個贊
通常,我將通常傳遞給遞歸函數的參數推送到堆棧中,從而將遞歸算法替換為迭代算法。實際上,您正在將程序堆棧替換為您自己的程序堆棧。
Stack<Object>?stack; stack.push(first_object); while(?!stack.isEmpty()?)?{ ???//?Do?something ???my_object?=?stack.pop(); ??//?Push?other?objects?on?the?stack. }
注意:如果您的內部有多個遞歸調用,并且希望保留調用的順序,則必須將它們以相反的順序添加到堆棧中:
foo(first); foo(second);
必須代之以
stack.push(second); stack.push(first);

ABOUTYOU
TA貢獻1812條經驗 獲得超5個贊
void quicksort(int* array, int left, int right) { if(left >= right) return; int index = partition(array, left, right); quicksort(array, left, index - 1); quicksort(array, index + 1, right); }
void quicksort(int *array, int left, int right) { int stack[1024]; int i=0; stack[i++] = left; stack[i++] = right; while (i > 0) { right = stack[--i]; left = stack[--i]; if (left >= right) continue; int index = partition(array, left, right); stack[i++] = left; stack[i++] = index - 1; stack[i++] = index + 1; stack[i++] = right; } }

尚方寶劍之說
TA貢獻1788條經驗 獲得超4個贊
似乎沒有人討論遞歸函數在主體中多次調用自己的位置,并處理返回到遞歸中的特定點(即不是原始遞歸)的問題。據說每個遞歸都可以轉化為迭代??磥磉@是可能的。
我只是想出了一個C#的例子來說明如何做到這一點。假設您有下面的遞歸函數,它的作用類似于一個后繼遍歷,而AbcTreeNode是一個具有指針a、b、c的三叉樹。
public?static?void?AbcRecursiveTraversal(this?AbcTreeNode?x,?List<int>?list)?{ ????????if?(x?!=?null)?{ ????????????AbcRecursiveTraversal(x.a,?list); ????????????AbcRecursiveTraversal(x.b,?list); ????????????AbcRecursiveTraversal(x.c,?list); ????????????list.Add(x.key);//finally?visit?root ????????} }
迭代解決方案:
????????int??address?=?null; ????????AbcTreeNode?x?=?null; ????????x?=?root; ????????address?=?A; ????????stack.Push(x); ????????stack.Push(null)???? ????????while?(stack.Count?>?0)?{ ????????????bool?@return?=?x?==?null; ????????????if?(@return?==?false)?{ ????????????????switch?(address)?{ ????????????????????case?A://??? ????????????????????????stack.Push(x); ????????????????????????stack.Push(B); ????????????????????????x?=?x.a; ????????????????????????address?=?A; ????????????????????????break; ????????????????????case?B: ????????????????????????stack.Push(x); ????????????????????????stack.Push(C); ????????????????????????x?=?x.b; ????????????????????????address?=?A; ????????????????????????break; ????????????????????case?C: ????????????????????????stack.Push(x); ????????????????????????stack.Push(null); ????????????????????????x?=?x.c; ????????????????????????address?=?A; ????????????????????????break; ????????????????????case?null: ????????????????????????list_iterative.Add(x.key); ????????????????????????@return?=?true; ????????????????????????break; ????????????????} ????????????} ????????????if?(@return?==?true)?{ ????????????????address?=?(int?)stack.Pop(); ????????????????x?=?(AbcTreeNode)stack.Pop(); ????????????} ????????}
添加回答
舉報
0/150
提交
取消