zz 递归算法转换为非递归算法
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 递归算法转换为非递归算法相关推荐
- 递归算法转换为非递归算法的技巧
递归算法转换为非递归算法的技巧 递归函数具有很好的可读性和可维护性,但是大部分情况下程序效率不如非递归函数,所以在程序设计中一般喜欢先用递归解决问题,在保证方法正确的前提下再转换为非递归函数以提高效率 ...
- 递归算法转换为非递归算法
转 自 : https://blog.csdn.net/fbz123456/article/details/50959412 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于 ...
- 递归算法到非递归算法的转换
递归实质在定义自身的同时又出现了对自身的调用.递归算法是许多软件编程人员常用的方法,结构简单.清晰.可读性好.但在实际应用中也存在一些问题:1.并不是每一门语言都支持递归,比较典型的FORTRAN语言 ...
- 递归算法向非递归算法转换
递归算法向非递归算法转换 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执 ...
- 递归算法与非递归算法的转化
递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某 些复杂问题(例如 hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式, 但是递归算法的执行效率通常比较差 ...
- 递归算法与非递归算法比较
转载自:https://blog.csdn.net/mhsszm/article/details/78445591 非递归效率高:递归代码写出来思路清晰,可读性强. 生成可执行文件大小应该和编译器有关 ...
- 遍历二叉树的递归算法与非递归算法
遍历二叉树的递归算法与非递归算法 先来看下面这棵二叉树.如图1.现在我们要对它进行先序遍历.递归思想:就是把这个大树拆分成N棵小树,每棵小树都进行一次先序遍历.再把这些遍历连合起来就是这棵树的先序遍历 ...
- Hanoi塔问题的递归算法与非递归算法
1. 递归算法: n=1时,很简单只需要将编号为1的圆盘从A移动到B即可. n>1时,只需要利用辅助塔C,先将n-1个较小的圆盘移动到C塔,再将剩下最大的圆盘移动到B塔,最后再将n-1个圆盘从C ...
- 斐波那契数列递归算法和非递归算法以及其时间复杂度分析
1.在学习数据结构这门课的过程中,发现斐波那契数列的递归算法以及非递归算法,以及其时间复杂度分析是一个小难点.所以特别总结一下. 斐波那契数列的表达式: Fibonacci数列简介: F(1)=1 F ...
最新文章
- Emptyproject分析
- 第十六届全国大学生智能车竞赛赛题规划
- 浅议DAS、NAS、SAN三种存储架构
- 强类型语言和静态类型语言有什么区别?
- Ruby/Rails 生态环境、社区、资料 Ecosystem
- Next Permutation
- java多条件组合查询6_elasticsearch组合多条件查询实现restful api以及java代码实现
- shell比较运算符
- C#操作IIS完整解析
- 韵达混合云深度解析:Docker助力大规模云上调度实践
- Silverlight 2 DataGrid December 2008
- [转载] python 字符串包含某个字符_python字符串
- python jupyter
- 警察抓小偷打字游戏JAVA_打字游戏警察抓小偷_警察抓小偷打字游戏下载[2012]-下载之家...
- 人工智能技术发展综述
- 京瓷1125打印机清零_京瓷1125驱动下载
- 多linux系统u盘制作,高手教你如何做一个U盘Linux系统
- numpy的随机抽样
- java模拟器安卓7,指小游Java模拟器
- 一张图理解贝叶斯公式