您的位置:首页 > 其它

算法:阶乘的五种算法

2013-12-02 17:50 351 查看

背景

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

第一种实现:递归

private static long RecursiveFac(long n)
{
if (n == 0)
{
return 1;
}
else
{
return n * RecursiveFac(n - 1);
}
}


第二种实现:递推

private static long Fac(long n)
{
var result = 1;

for (var i = 1; i <= n; i++)
{
result = result * i;
}

return result;
}


第三种实现:尾递归

private static int TailRecursiveFac(int n, int accumulator)
{
if (n == 0)
{
return accumulator;
}

return Fac(n - 1, n * accumulator);
}


第四种实现:消除尾递归

private static int Fac(int n, int accumulator)
{
while (true)
{
var tempN = n;
var tempAccumulator = accumulator;

if (tempN == 0)
{
return tempAccumulator;
}

n = tempN - 1;
accumulator = tempN * tempAccumulator;
}
}


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

private enum CodeAddress
{
Start,
AfterFirstRecursiveCall
}

private class StackFrame
{
public long N { get; set; }

public long FirstRecursiveCallResult { get; set; }

public CodeAddress CodeAddress { get; set; }
}

private static long StackFac(long n)
{
var stack = new Stack<StackFrame>();
stack.Push(new StackFrame
{
N = n,
CodeAddress = CodeAddress.Start
});

long result = 0;

while (stack.Count > 0)
{
var current = stack.Peek();

switch (current.CodeAddress)
{
case CodeAddress.Start:
if (current.N == 0)
{
result = 1;
stack.Pop();
}
else
{
current.CodeAddress = CodeAddress.AfterFirstRecursiveCall;
stack.Push(new StackFrame
{
N = current.N - 1,
CodeAddress = CodeAddress.Start
});
}
break;
case CodeAddress.AfterFirstRecursiveCall:
current.FirstRecursiveCallResult = result;

result = current.N * current.FirstRecursiveCallResult;
stack.Pop();
break;
}
}

return result;
}


备注

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: