from:http://blog.csdn.net/Shunrei/archive/2010/06/19/5680579.aspx

递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解。对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执行效率通常比较差。因此,在求解某些问题时,常采用递归算法来分析问题,用非递归算法来求解问题;另外,有些程序设计语言不支持递归,这就需要把递归算法转换为非递归算法。
    将递归算法转换为非递归算法有两种方法,一种是直接求值(迭代/循环),不需要回溯;另一种是不能直接求值,需要回溯。前者使用一些变量保存中间结果,称为直接转换法;后者使用栈保存中间结果,称为间接转换法,下面分别讨论这两种方法。

  1. 直接转换法 
  直接转换法通常用来消除尾递归和单向递归,将递归结构用循环结构来替代。
  单向递归:简单的说是指递归的过程总是朝着一个方向进行,如果函数1调用了函数2,而函数2又调用了函数1,则这种情况不属于单向递归。斐波那契数列的递归求解可转用一个迭代法实现。

 斐波那契数列的递归求解:

 int Fib(int n) {
   if(n <= 1) return n;
   else return Fib(n - 1) + Fib(n - 2);
 }

 转化为迭代求解:

int Fib(int n) {
   if(n <= 1) return n;
  int twoBack = 0;
   int oneBack = 1;
   int cur;
  for(int i = 2;i < = n; i++) {
      cur = twoBack + oneBack;
    twoBack = oneBack;
      oneBack = cur;
   }
   return cur;
}

  尾递归函数是以递归调用结尾的函数,是单向递归的特例。它的递归调用语句只有一个,而且是放在过程的最后。当递归调用返回时,返回到上一层递归调用语句的下一语句,而这个位置正好是程序的结尾,因此递归工作栈中可以不保存返回地址;除了返回值和引用值外,其他参数和局部变量都不再需要,因此可以不用栈,直接采用循环写出非递归过程。

  阶乘函数就不是一个尾递归。因为在它收到递归调用的结果后,必须在返回调用前再做一次乘法运算。但是阶乘函数可以转化成一个尾递归函数,例:

阶乘的递归求解:

int factorial(int n)

{
   if(n == 0) return 1;
   else

{
    int val = factorial(n - 1);
    return n * val;
   }
}

转化为尾递归求解:

int factorial(int acc, int x)

{ //acc传的值为1。
  if(x <= 1) return acc;
  else

return factorial(x * acc, x - 1);
}

  尾递归的重要性在于当进行尾递归调用时,调用者的返回位置不需要被存在调用栈里。当递归调用返回时,它直接分支到先前已保存的返回地址。因此,在支持尾递归优化的编译器上,尾递归在时间和空间上都比较划算。迭代算法需要一个临时变量,这无疑导致了程序的可读性降低,迭代函数不像递归函数那样需要考虑函数调用的支出,而且对一个线程来说可用的栈空间通常比可用的堆空间要少得多,而递归算法则相对迭代算法需要更多的栈空间!

2. 间接转换法 
  该方法使用栈保存中间结果,一般需根据递归函数在执行过程中栈的变化得到。其一般过程如下:

  将初始状态s0进栈
  while (栈不为空)
  {
  退栈,将栈顶元素赋给s;
  if (s是要找的结果) 返回;
  else {
  寻找到s的相关状态s1;
  将s1进栈
  }
  }

  间接转换法在数据结构中有较多实例,如二叉树遍历算法的非递归实现、图的深度优先遍历算法的非递归实现等等,请读者参考主教材中相关内容。

转载于:https://www.cnblogs.com/little-rookie/archive/2011/05/07/2039819.html

zz 递归算法转换为非递归算法相关推荐

  1. 递归算法转换为非递归算法的技巧

    递归算法转换为非递归算法的技巧 递归函数具有很好的可读性和可维护性,但是大部分情况下程序效率不如非递归函数,所以在程序设计中一般喜欢先用递归解决问题,在保证方法正确的前提下再转换为非递归函数以提高效率 ...

  2. 递归算法转换为非递归算法

    转 自 : https://blog.csdn.net/fbz123456/article/details/50959412 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于 ...

  3. 递归算法到非递归算法的转换

    递归实质在定义自身的同时又出现了对自身的调用.递归算法是许多软件编程人员常用的方法,结构简单.清晰.可读性好.但在实际应用中也存在一些问题:1.并不是每一门语言都支持递归,比较典型的FORTRAN语言 ...

  4. 递归算法向非递归算法转换

    递归算法向非递归算法转换 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执 ...

  5. 递归算法与非递归算法的转化

    递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某  些复杂问题(例如 hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,  但是递归算法的执行效率通常比较差 ...

  6. 递归算法与非递归算法比较

    转载自:https://blog.csdn.net/mhsszm/article/details/78445591 非递归效率高:递归代码写出来思路清晰,可读性强. 生成可执行文件大小应该和编译器有关 ...

  7. 遍历二叉树的递归算法与非递归算法

    遍历二叉树的递归算法与非递归算法 先来看下面这棵二叉树.如图1.现在我们要对它进行先序遍历.递归思想:就是把这个大树拆分成N棵小树,每棵小树都进行一次先序遍历.再把这些遍历连合起来就是这棵树的先序遍历 ...

  8. Hanoi塔问题的递归算法与非递归算法

    1. 递归算法: n=1时,很简单只需要将编号为1的圆盘从A移动到B即可. n>1时,只需要利用辅助塔C,先将n-1个较小的圆盘移动到C塔,再将剩下最大的圆盘移动到B塔,最后再将n-1个圆盘从C ...

  9. 斐波那契数列递归算法和非递归算法以及其时间复杂度分析

    1.在学习数据结构这门课的过程中,发现斐波那契数列的递归算法以及非递归算法,以及其时间复杂度分析是一个小难点.所以特别总结一下. 斐波那契数列的表达式: Fibonacci数列简介: F(1)=1 F ...

最新文章

  1. Emptyproject分析
  2. 第十六届全国大学生智能车竞赛赛题规划
  3. 浅议DAS、NAS、SAN三种存储架构
  4. 强类型语言和静态类型语言有什么区别?
  5. Ruby/Rails 生态环境、社区、资料 Ecosystem
  6. Next Permutation
  7. java多条件组合查询6_elasticsearch组合多条件查询实现restful api以及java代码实现
  8. shell比较运算符
  9. C#操作IIS完整解析
  10. 韵达混合云深度解析:Docker助力大规模云上调度实践
  11. Silverlight 2 DataGrid December 2008
  12. [转载] python 字符串包含某个字符_python字符串
  13. python jupyter
  14. 警察抓小偷打字游戏JAVA_打字游戏警察抓小偷_警察抓小偷打字游戏下载[2012]-下载之家...
  15. 人工智能技术发展综述
  16. 京瓷1125打印机清零_京瓷1125驱动下载
  17. 多linux系统u盘制作,高手教你如何做一个U盘Linux系统
  18. numpy的随机抽样
  19. java模拟器安卓7,指小游Java模拟器
  20. 一张图理解贝叶斯公式

热门文章

  1. jQuery仿淘宝商城天猫鼠标移动过去,透明度降低
  2. oracle实例无法启动也无法关闭
  3. java EE的apache-tomcat配置文件web.xml
  4. 【洛谷 2782】友好城市
  5. java常用类--------File类基本用法
  6. Android-----application的学习
  7. XVI Open Cup named after E.V. Pankratiev. GP of Ekaterinburg
  8. 开源学习:tinyhttpd
  9. MySQL批量插入数据的几种方法
  10. 2011考研英语词汇最佳记忆法 考量你的遗忘曲线