用递归代码实现斐波那契数列求解,利用转换规则(不简化) 将递归代码转换为非递归代码。(C++)

用递归代码实现斐波那契数列求解,利用转换规则(不简化) 将递归代码转换为非递归代码。(C++)

 这次作业记得是五一时候做的,当时快放假时布置的,想了很久也没想出来怎么转化。
 五一时做火车出去玩,还是在火车上突然就有了灵感,就写出来了。
 不过,到现在时间已经有点长了,所以也记得不太清楚了,就简单的根据当时的作业报告,简单写一下吧。

转换规则如下:
(1) 设置一个栈(不妨用S表示),并且开始时将其置为空。

(2) 在子程序入口处设置一个标号(不妨设为L0)。

(3) 对子程序中的每一递归调用,用以下几个等价操作来替换:

(a)保留现场:开辟栈顶存储空间,用于保存返回地址(不妨用 Li,i=1,2,3,…)、调用层中的形参和局部变量的值(最外层调用不必考虑)。

(b)准备数据:为被调子程序准备数据,即计算实在参数的值, 并赋给对应的形参

(c)转入(子程序)执行, 即执行goto L0。

(d)在返回处设一个标号Li(i=1,2,3,…),并根据需要设置以下语句:若函数需要返回值,从回传变量中取出所保存的值并传送到相应的位置。

(4) 对返回语句,可用以下几个等价操作来替换:

如果栈不空,则依次执行如下操作,否则结束本子程序,返回。
(a)回传数据:若函数需要返回值,将其值保存到回传变量中。
(b)恢复现场:从栈顶取出返回地址(不妨保存到X中)及各
变量、形参值,并退栈。
(c)返回:按返回地址返回(即执行goto X)。

(5)对其中的非递归调用和返回操作可照搬。

流程图如下:
在这里插入图片描述

测试结果:
n=1时。
在这里插入图片描述
n=4时。
在这里插入图片描述
n=10时
在这里插入图片描述

源代码如下:

#include<iostream>
#include<stack>
using namespace std;
int  digui(int n);//递归实现
int nodigui(int n);//不简化的递归等价转换
int jianhua_dg(int n);//简化的递归转换
int main()
{
	cout << "请输入数列的层数n:";
	int n;
	cin >> n;
	cout << "斐波那契数列为:" << digui(n) << endl;
	cout << "斐波那契数列非递归调用为:" << nodigui(n) << endl;
	cout << "斐波那契数列非递归简化后的调用结果为:" << jianhua_dg(n) << endl;
	return 0;
}
int digui(int n)
{
	if (n == 1 || n == 2)
		return 1;
	else
		return  digui(n - 1) + digui(n - 2);
}
int nodigui(int n)
{
	if (n == 1 || n == 2)//相当于规则5照搬
		return 1;
	stack<int> s;//规则1
	int s1 = 1, s2 = 1;//规则5
	int ret;
L0://规则2
	if(n>=3)     //规则3
	{
		s.push(n);
		s.push(1);//3.a
		n -= 1;//3.b
		goto L0;//3.c
	L1:        //3.d
		s.push(n);//3.a
		s.push(2);//3.a
		n -= 2;//3.b
		goto L0;//3.c
	L2://3.d
		ret = s1 + s2;//规则5
		s2 = s1;
		s1 = ret;
	}
	if (!s.empty())//规则4
	{
		int x;
		x = s.top();//4.a
		s.pop();//4.b
		s.pop();//4.b
		if(x == 1)  goto L1;//4.c
	    else goto L2;//4.c
	}
	return ret;
}
int jianhua_dg(int n)
{
	if (n == 1 || n == 2)
		return 1;
	int s1 = 1, s2 = 1;
	int ret;
	for (int i = 3; i <= n; i++)
	{
		ret = s1 + s2;
		s2 = s1;
		s1 = ret;
	}
	return ret;
}

  • 19
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值