算法

发布时间:2025-12-09 11:58:40 浏览次数:1

背景

周末温习了一下递归相关的一些概念,本文先给出阶乘的五种算法。

第一种实现:递归

 1         private static long RecursiveFac(long n) 2         { 3             if (n == 0) 4             { 5                 return 1; 6             } 7             else 8             { 9                 return n * RecursiveFac(n - 1);10             }11         }

第二种实现:递推

 1         private static long Fac(long n) 2         { 3             var result = 1; 4  5             for (var i = 1; i <= n; i++) 6             { 7                 result = result * i; 8             } 9 10             return result;11         }

第三种实现:尾递归

1         private static int TailRecursiveFac(int n, int accumulator)2         {3             if (n == 0)4             {5                 return accumulator;6             }7 8             return Fac(n - 1, n * accumulator);9         }

第四种实现:消除尾递归

 1         private static int Fac(int n, int accumulator) 2         { 3             while (true) 4             { 5                 var tempN = n; 6                 var tempAccumulator = accumulator; 7  8                 if (tempN == 0) 9                 {10                     return tempAccumulator;11                 }12 13                 n = tempN - 1;14                 accumulator = tempN * tempAccumulator;15             }16         }

第五种实现:堆栈(堆中分配的栈)替换函数栈

 1         private enum CodeAddress 2         { 3             Start, 4             AfterFirstRecursiveCall 5         } 6  7         private class StackFrame 8         { 9             public long N { get; set; }10 11             public long FirstRecursiveCallResult { get; set; }12 13             public CodeAddress CodeAddress { get; set; }14         }15 16         private static long StackFac(long n)17         {18             var stack = new Stack<StackFrame>();19             stack.Push(new StackFrame20             {21                 N = n,22                 CodeAddress = CodeAddress.Start23             });24 25             long result = 0;26 27             while (stack.Count > 0)28             {29                 var current = stack.Peek();30 31                 switch (current.CodeAddress)32                 {33                     case CodeAddress.Start:34                         if (current.N == 0)35                         {36                             result = 1;37                             stack.Pop();38                         }39                         else40                         {41                             current.CodeAddress = CodeAddress.AfterFirstRecursiveCall;42                             stack.Push(new StackFrame43                             {44                                 N = current.N - 1,45                                 CodeAddress = CodeAddress.Start46                             });47                         }48                         break;49                     case CodeAddress.AfterFirstRecursiveCall:50                         current.FirstRecursiveCallResult = result;51 52                         result = current.N * current.FirstRecursiveCallResult;53                         stack.Pop();54                         break;55                 }56             }57 58             return result;59         }

备注

这里比较有意思的实现是:尾递归和基于堆中的栈的递归,本文先不详细介绍了,后面再细说,有兴趣的朋友先看如下资源:

  • Replacing Recursion With a Stack。
  • How to replace recursive functions using stack and while-loop to avoid the stack-overflow。
  • HOW TO CONVERT A RECURSIVE ALGORITHM TO A NON-RECURSIVE ONE。
  • replace Recursion with Iteration。
  • Provide an explanation of recursion, including an example。
  • Tail Recursion。
  • Understanding Tail Recursion。

155051.html

阶乘算法
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477