1. 程式人生 > >遞歸、遞推和叠代的區別

遞歸、遞推和叠代的區別

fibonacci stop 循環計算 span 函數 bubuko 計算 log ati

遞歸:函數本身調用自己,實現自身循環。例如:求斐波那契數

一列數的規則如下: 1、1、2、3、5、8、13、21、34...... 求第30位數是多少,

        /// <summary>
        /// 用遞歸算法實現斐波那契
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public static int Fibonacci_recursion(int i)
        {
            
if (i <= 0) { return 0; } else if (i > 0 && i <= 2) { return 1; } else { return Fibonacci_recursion(i - 1) + Fibonacci_recursion(i - 2); } }

遞推:根據其已有的數據和關系,逐步推導而得到結果的這個過程。

        /// <summary>
        /// 遞推算法實現斐波那契
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static int Fibonacci_recurrence(int n)
        {
            if (n <= 0)
                
throw new ArgumentOutOfRangeException(); int a = 1,b = 1; for (int i = 3; i <= n; i++) { b = checked(a + b); a = b - a; } return b; }

例如傳入的數為46,求第46位斐波那契數,遞歸與遞推的結果與消耗時間分別是:

            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            Console.WriteLine("遞歸結果:" + Logic.Fibonacci_recursion(46));
            TimeSpan ts2 = sw1.Elapsed;
            Console.WriteLine("遞歸算法耗時:" + ts2);
            sw1.Stop();

            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
            Console.WriteLine("遞推結果:" + Logic.Fibonacci_recurrence(46));
            sw2.Stop();
            TimeSpan ts1= sw2.Elapsed;
            Console.WriteLine("遞推算法耗時:" + ts1);

技術分享圖片

由此可見遞歸和遞推的算法消耗的時間差點一點半點,這個是因為遞歸每次都要壓棧出棧,所以空間消耗要比非遞歸代碼要大很多。而且如果遞歸深度太大,可能系統撐不住。

叠代比較簡單了,叠代也是一種循環,與循環不同的是 運算變量的同時保存變量的值,保存的結果作為下次循環計算的初始值。 例如:C#中的 yield 關鍵字

      public IEnumerable<int> GetList()
      {
           int i = 0;
           while (i < 10)
           {
              i++;
              yield return i;
           }
      }

遞歸、遞推和叠代的區別