遞歸轉非遞歸(學習筆記)

在網上逛的時候發現一篇好文 遞歸轉非遞歸 ,閱讀完,覺得有啓發,把重點記錄下來,另外作者是用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中測試通過.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章