背景

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

第一种实现:递归

 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         }

备注

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

  • 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。

算法:阶乘的五种算法相关推荐

  1. Java代码实现负载均衡五种算法

    前言: 负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给各个server.其中有好几个种经典的算法.在用java代码编写这几种算法之前,先来了解一下负载均衡这个概念. 1. ...

  2. 三维点云学习(2)五种算法比较

    三维点云学习(2)五种算法比较 代码参考来自 黎老师github 本次测试包含五种算法比较: octree print("octree --------------")#时间统计c ...

  3. 路径规划五种算法简述及对比

    以下是本人在学习路径规划过程中的一些总结,借着机会写了一下,有不妥之处欢迎批评指正,谢谢. 路径规划部分在无人车架构体系当中分属控制或决策部分,如图1,是实现无人化驾驶的关键技术之一.路径规划模块性能 ...

  4. lfu算法实现java_LFU五种实现方式,从简单到复杂

    前言 最近刷力扣题,对于我这种 0 基础来说,真的是脑壳疼啊.这个月我估计都是中等和困难题,没有简单题了. 幸好,力扣上有各种大牛给写题解.看着他们行云流水的代码,真的是羡慕不已.让我印象最深刻的就是 ...

  5. 算法简介、7种算法分类

    一.算法 算法是以函数模板的形式实现的.常用的算法涉及到比较.交换.查找.搜索.复制.修改.移除.反转.排序.合并等等. 算法并非容器类型的成员函数,而是一些全局函数,要与迭代器一起搭配使用. 算法的 ...

  6. 数据结构和算法之常用 10 种算法

    目录 1.二分查找算法(非递归) 2.分治算法 2.1分治算法最佳实践-汉诺塔 3.动态规划算法 4.KMP 算法 4.1KMP 算法最佳应用-字符串匹配问题 5.贪心算法 5.1贪心算法最佳应用-集 ...

  7. 自动驾驶系列(二) - 路径规划五种算法简述及对比

  8. 语言高精度算法阶乘_JavaScript中的算法(附10道面试常见算法题解决方法和思路)...

    https://juejin.im/post/6844903811505455118 Introduction 面试过程通常从最初的电话面试开始,然后是现场面试,检查编程技能和文化契合度.几乎毫无例外 ...

  9. Python算法练习(五)// 算法:KMeans,数据集:标准普尔500指数

    本练习利用KMeans算法对标准普尔500指数的股票进行聚类,为进一步投资提供决策参考.该数据集有2个特征,借助散点图明显看出股票可以分为4类.建立模型后,通过肘部法和轮廓系数得到最佳的簇数为4.最后 ...

最新文章

  1. linux下git的简单使用
  2. python正则group()的用法—正则提取括号内以及其他符号内内容
  3. C语言打印九九乘法口诀
  4. 【jzoj】2018.1.31 NOIP普及组——D组模拟赛
  5. NOIP2011 铺地毯
  6. 传统手工特征--opencv
  7. 李佳琦“云逛”进博会 携手央视带货阿富汗松子
  8. c语言制作图片软件,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
  9. 静态函数 静态变量和常量
  10. 『ORACLE』 DG性能转换(11g)
  11. 【直接下载】x86_64-6.3.0-release-win32-seh-rt_v5-rev2
  12. excel导入,用反射匹配字段名
  13. 常见的HTPP状态码
  14. python如何拼读英语单词怎么写_浅谈如何拼读英语新单词
  15. 基于android的lbs技术,基于Android的LBS系统研究
  16. Ubuntu开发嵌入式串口权限问题
  17. R语言读取文件报错之二:Error in read.table(“xxxx.txt“, header = TRUE) : 列的数目比列的名字要多
  18. 【数据处理】格式化数据
  19. Netty源码实战(十) - 性能优化
  20. shell卸载 simatic_Siemens Simatic WinCC v7.5 SP1 (x64)ISO 授权安装教程

热门文章

  1. python 数据流中的移动平均值_剑指Offer-41-数据流中的中位数
  2. pandas 每一列相加_Python3 numpy amp; pandas 学习笔记
  3. php如何实现购物时数量增减,1、vuex状态管理--购物车数量增减
  4. python字符串出栈方法_1.Python实现字符串反转的几种方法
  5. springboot中接口实例化_AngularJs中控制器的定义,实例化,作用域范围
  6. C语言、C++学习路线
  7. document.getElementById()与 $()区别
  8. idea for循环快捷键_IDEA骚技巧,编码速度至少快一倍
  9. checkbox wpf 改变框的大小_【论文阅读】倾斜目标范围框(标注)的终极方案
  10. php访问js文件不存在,php文件里js不能被执行