递归算法转化为非递归算法

(1)直接用循环结构的算法替代递归算法(直接转化法,不需要使用栈
(2)用栈模拟系统的运行过程,通过分析只保存必须保存的信息,从而用非递归方法替代递归算法。(间接转化法,需要使用栈

用循环结构替代递归过程:
采用循环结构消除递归这种直接转化法没有通用的转换算法,对于具体问题要深入分析对应的递归结构,设计有效的循环语句进行递归到非递归的转换。
直接转化法特别适合于尾递归。尾递归只有一个递归调用语句,而且是出于算法的最后。

比如求阶乘的算法

//递归实现
#include<stdio.h>
int fun(int n)
{
	if(n==1)
 		return 1;
 	else
 		return fun(n-1)*n;
}
int main()
{
	printf("%d",fun(3));
	return 0;
} 

用直接转换法转换成非递归的算法:

//非递归实现
#include<stdio.h>
int fun(int n)
{
	int M = 1;
	for(int i = 1; i <= n; i ++)
	{
		M*=i;
	}
	return M;
}
int main()
{
	printf("%d",fun(3));
	
	return 0;
} 

直接转化法也适合于单向递归。单向递归指递归函数中虽然有一处以上的递归调用语句,但各次递归调用语句的参数只和主调用函数有关,相互之间参数无关,并且这些递归调用语句也和尾递归一样处于算法的最后。

求Fibonacci数列

//递归算法实现
int Fib(int n)
{
	if(n == 1||n == 2)
		return 1;
	return Fib(n - 1)+Fib(n - 2);
}
//非递归算法实现
int Fib1(int n)
{
	int i,f1,f2,f3;
	if(n == 1||n == 2)
		return 1;
	f1=1,f2=1;
	for(int i = 3; i <= n; i++)
	{
		f3 = f1 + f2;
		f1 = f2;
		f2 = f3;
	}
	return f3;
}

用栈消除递归过程

通常使用栈保存中间结果,从而将递归算法转化为非递归算法的过程。
在设计栈时,除了保存递归函数的参数等外,还要增加一个标志成员(tag),对于某个递归小问题f(s’),其值为1表示对应递归问题尚未求出,需进一步分解转换,为0表示对用递归问题已求出,需通过该结果求解大问题f(s)。
为了方便讨论,将地规模型分为等值关系等价关系两种。
等值关系是指“大问题”的函数值等于“小问题”的函数值的某种运算结果。
例如求n!对应的递归模型就是等值关系。
在这里插入图片描述

#include<stdio.h>
#include<stack>
using namespace std;

struct NodeType//栈元素类型
{
	int n;//保存n值
	int f;//保存f(n)值
	int tag;//标识是否求出f(n)值,1:未求出,0:已求出 
};
int fun2(int n)
{
	NodeType e, e1, e2;
	stack<NodeType> st;
	
	e.n = n;//现在要求n的阶乘,原始n 
	e.tag = 1;//还未求出
	st.push(e);//初值进栈
	while(!st.empty())//栈不空时循环
	{
		if(st.top().tag == 1)//未计算出栈顶元素的f值
		{
			if(st.top().n == 1)
			{
				st.top().f = 1;//直接赋予阶乘值
				st.top().tag = 0;//标识已求出 
			} 
			else
			{
				e1.n = st.top().n - 1;//构建新元素e1,标识要求st.top()
				e1.tag = 1;//标识还未求出
				st.push(e1);//子任务进栈,下一次循环时处理 
			}
		}
		else //st.top().tag = 0,即已计算出栈顶元素的f值 
		{
			e2 = st.top();
			st.pop();//退栈e2
			st.top().f = st.top().n *e2.f;//根据递推式
			st.top().tag = 0; 
		} 
		if(st.size() == 1&& st.top().tag == 0) 
			break;
	}
	return st.top().f; 
}

int main()
{
	printf("%d",fun2(6));
}

等价关系是指“大问题”的求解过程转化为“小问题”求解而得到的,他们之间不是值的相等关系,而是解的等价关系。
例如,求梵塔问题对应的递归模型就是等价关系,也即是说,Hanoi(n,x,y,z)与Hanoi(n-1,x,z,y)、move(n,x,z)和Hanoi(n-1,y,x,z)是等价的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁月辰星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值