在網上逛的時候發現一篇好文 遞歸轉非遞歸 ,閱讀完,覺得有啓發,把重點記錄下來,另外作者是用ISO C++語言描述的,我在測試的時候把它改成C#2.0的拉:
爲什麼要遞歸轉非遞歸:
因爲每一次的遞歸調用都需要壓棧佔用內存,效率不高.
遞歸轉非遞歸的兩種方法:
下面以求n的階乘來說明
先給出一般的遞歸方法:
1 /**//// <summary>
2 /// 遞歸求階乘
3 /// </summary>
4 private int Factorial(int n)
5 {
6 if (n > 1)
7 {
8 return n * Factorial(n - 1);
9 }
10 else if (n == 1)
11 {
12 return 1;
13 }
14 else
15 {
16 throw new ArgumentException("Argument Error");
17 }
18 }
非遞歸方法一:循環法,前提是,待解決問題必須能夠分解出可循環規律方可
而n! = n! = n*(n-1)*(n-2)*....*1;從循環的角度理解就是:n!表示執行n次循環計算一個增量k,初始k=1和結果t=1;每次t乘以k++的值.從而可以得到:
1 /**//// <summary>
2 /// 循環求階乘
3 /// </summary>
4 private int FactorialByLoop(int n)
5 {
6 int k = 1;
7 int t = 1;
8 while (k <= n)
9 {
10 t *= k;
11 k++;
12 }
13
14 return t;
15 }
非遞歸方法二:自定義堆棧法,目的是爲不能分析出來循環的遞歸操作提供開銷可控的方法.如:
1 /**//// <summary>
2 /// 自定義堆棧求階乘
3 /// </summary>
4 private int FactorialByStack(int n)
5 {
6 Stack<int> s = new Stack<int>();
7 int t = 1;
8 int temp;
9 s.Push(n);
10 while ((temp = s.Peek()) != 1)
11 {
12 t *= s.Peek();
13 s.Pop();
14 s.Push(temp - 1);
15 }
16 return t;
17 }
說明:以上代碼在Visual Studio 2005 Express中測試通過.