递归

目录

背景第一种实现:递归第二种实现:递推第三种实现:尾递归第四种实现:消除尾递归第五种实现:堆栈(堆中分配的栈)替换函数栈备注

背景返回目录

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

第一种实现:递归返回目录

复制代码
 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 StackFrame

20             {

21                 N = n,

22                 CodeAddress = CodeAddress.Start

23             });

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                         else

40                         {

41                             current.CodeAddress = CodeAddress.AfterFirstRecursiveCall;

42                             stack.Push(new StackFrame

43                             {

44                                 N = current.N - 1,

45                                 CodeAddress = CodeAddress.Start

46                             });

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         }
复制代码

备注返回目录

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

 

你可能感兴趣的:(递归)