【数据结构】 实验报告09 将递归代码转换为非递归代码

数据结构实验-递归 1/输出n个整数的全排列。 2、输出n个整数的所有子集。 立即下载

一、实验目的和要求

目的:将阶乘的递归算法一步一步转换为非递归算法

要求:其它要求同作业-01要求。

二、实验环境

软件环境:visual stdio 2017
硬件环境:①CPU:Intel(R)Core(TM)i7-8565U CPU @1.80Ghz
②内存:8.0GB

三、实验内容

(1)用递归代码实现n!求解。
(2)利用转换规则(不简化) 将代码(1)转换为非递归代码。
(3)简化并梳理代码(2)的流程。
(4)用以上三个独立模块,测试6!的计算结果。

四、实验过程

4.1 任务定义和问题分析

运用转换规则将阶乘递归算法转换为非递归算法,再经过简化规则得到最终版本。

4.2 数据结构的选择和概要设计

涉及到的数据结构:自行设计的链栈,传入参数为2个,一个记录数据,一个记录“地址”
概要设计:第一个函数:阶乘递归算法
第二个函数:仅使用转换规则得到的非递归算法
第三个函数:经化简规则得到的非递归算法

4.3 详细设计

函数1:简单的尾递归算法
在这里插入图片描述
函数2:由五个规则进行转换
(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) 对其中的非递归调用和返回操作可照搬。
在这里插入图片描述

函数三:用简化规则进行简化
简化规则1:如果递归程序中只有一处递归调用,则在转换时,返回地址不必入栈。
由此可简化程序,得到流程图及相应的程序。
简化规则2:在模拟尾递归调用时,不必执行入栈操作。
经化简规则,可以得到流程图如下:
在这里插入图片描述
因此,可以写出代码如下:
在这里插入图片描述

五、测试及结果分析

5.1 实验数据

用三个函数测试6!的结果

5.2 结果及分析

六、实验收获

经过本次实验,我学会了如何将递归代码转换为非递归代码,这也说明了,有些非递归代码可以用递归实现,这样可以使代码简洁许多。

七、参考文献

教学ppt

八、附录(源代码)

#include<iostream>
using namespace std;
template<typename T>
struct Node
{
	T data;
	Node*next;
};
template<typename T>
class stack
{
public:
	stack()
	{
		top1 = new Node<T>;
		top1->next = NULL;
		top2 = new Node<int>;
		top2->next = NULL;
	}
	bool empty() { return top1 == NULL; }
	void push(T data, int address)
	{
		Node<T>*s1 = new Node<T>;
		s1->data = data;
		s1->next = top1;
		top1 = s1;
		Node<int>*s2 = new Node<int>;
		s2->data = address;
		s2->next = top2;
		top2 = s2;
	}
	void pop(T& data, int& address)
	{
		data = top1->data;
		address = top2->data;
		Node<T>*s1 = new Node<T>;
		s1 = top1;
		top1 = s1->next;
		delete s1;
		Node<T>*s2 = new Node<int>;
		s2 = top2;
		top2 = s2->next;
		delete s2;
	}
private:
	Node<T>*top1;
	Node<int>* top2;
};

int fact(int n)
{
	if (n == 0)  return 1;
	return n * fact(n - 1);
		
}

int version1(int n)
{
	stack<int> s;       //规则1
	int base = 1;       //规则5
L0:                     //规则2
	if (n > 0)          //规则5
	{
		base *= n;      //规则5 
		s.push(n-1, 1); //规则3.a
		n = n - 1;      //规则3.b
		goto L0;        //规则3.c
	L1:;                //规则3.d
	}                
	if (!s.empty())     //规则4
	{
		int X;          //规则4.a
	s.pop(n, X);        //规则4.b
	if (X == 1) goto L1;//规则4.c
	}
	return base;        //规则5
}

int version2(int n)
{
	int base = 1;
	while (n > 0)
	{
		base *= n--;
	}
	return base;
}
int main()
{
	cout << fact(6) << endl;
	cout << version1(6) << endl;
	cout << version2(6) << endl;
}
数据结构中回溯与递归实验报告 数据结构或算法中回溯与递归的具体的实验报告。 立即下载

相关推荐

用Gazebo仿真无人机视觉SLAM:ORB-SLAM2+RGB-D相机完整调试记录

本文详细介绍了在Gazebo仿真环境中优化ORB-SLAM2用于无人机视觉SLAM的完整调试过程。通过定制传感器配置、调整ORB-SLAM2参数以及优化点云处理策略,显著提升了无人机在仿真环境中的SLAM性能。文章还提供了实用的调试技巧和性能评估方法,帮助开发者高效实现无人机视觉SLAM系统的仿真测试。

weixin_30485379的博客 450

数据结构作业——递归与非递归:(1)用递归代码实现斐波那契数列求解;(2)利用转换规则(goto) 将代码(1)转换为非递归代码;(3)简化并梳理代码(2);(4)递归斐波那契数列最优解

(1)用递归代码实现斐波那契数列求解;(2)利用转换规则(goto) 将代码(1)转换为非递归代码;(3)简化并梳理代码(2);(4)递归斐波那契数列最优解;利用递归求出前两项求和得到第三项,依次递增求解;利用goto实现强跳转,转到程序的某个片段中,用栈记录参数和返回的位置,利用栈的特性依次出栈实现递归的思想,将新元素入栈实现新数据的连续计算;在判断时,使用 ? : 语句简化代码;

Etayo2389941277的博客 454

告别黑窗口:XShell+X11转发图形化界面的5分钟保姆级教程(附Xming配置)

本文详细介绍了如何使用XShell和X11转发技术快速实现Linux图形化界面的远程访问。通过5分钟快速配置指南,包括服务端设置、客户端工具选择及XShell+Xming的完美配置,帮助用户高效运行GUI应用程序,提升远程工作效率。特别适合需要图形化操作的开发者和运维人员。

weixin_29223603的博客 328

数据结构实验4---递归

一、实验目的 1、掌握递归原理 2、掌握一些常用问题的递归算法设计 二、实验内容 1.编写一个连加运算递归函数ADD(n),实现从1+2+……+n。 2. 编写折半查找算法的递归实现和非递归实现。 提示:将要查找的元素key与查找区间正中元素相比,若key小,则查找区间缩小至前半部份查找,若key大,则查找区间缩小至后半部份查找;再取其中值比较,每次缩小1/2的范围,直到查找成功或失败为止。如递归实现,考虑函数的参数应有哪些。在用循环结构实现时,函数的参数有什么变化? 3.因子分解问题。大于1的.

qq_66451743的博客 1116

SpyGlass CDC实战:如何用sgdc约束文件解决跨时钟域报错(附常见错误排查)

本文详细介绍了如何使用SpyGlass CDC工具编写sgdc约束文件解决跨时钟域(CDC)报错问题。从基础语法到实战案例,涵盖时钟声明、复位约束、路径豁免等关键技巧,特别针对SPI断续时钟等特殊场景提供解决方案,并附常见错误排查指南,帮助工程师高效完成CDC验证。

weixin_28744423的博客 627

共聚焦显微镜的光源、工作原理与选型

共聚焦显微镜作为科研与工业领域中重要的微观成像工具,凭借光源的精准适配性、光学切片技术的三维成像能力,以及对不同工业场景的定制化适配潜力,为半导体检测、工业部件分析、智能制造升级提供了关键技术支撑。深入理解其光源特性、工作原理与选型逻辑,能帮助工程师与技术人员精准匹配设备与生产需求,既保障微观检测的精度与效率,又为产业优化、技术创新筑牢微观观测的基础。

PhotonixBay的博客 1540

将递归函数转成非递归函数的通用方法

下面我们做一个简单的总结:我们写的程序需要翻译成指令才能被执行,在 03 课时中我们提到过,这个翻译工具叫作编译器。平时你编程做的事情,用机器指令也能做,所以从计算能力上来说它们是等价的,最终这种计算能力又和图灵机是等价的。如果一个语言的能力和图灵机等价,我们就说这个语言是图灵完备的语言。现在市面上的绝大多数语言都是图灵完备的语言,但也有一些不是,比如 HTML、正则表达式和 SQL 等。我们通过汇编语言构造高级程序;通过高级程序构造自己的业务逻辑,这些都是工程能力的一种体现。

qq_37247026的博客 951

深度学习【46】pix2pixHD

英伟达的pix2pixHD,能够合成高清的2048*1024图片,简直振奋人心。pix2pixHD是我之前介绍过的pix2pix的改进版本,使用多由粗到精的G网络和多尺度D网络(每个D网络都是用了pix2pix中同样的patch技术)。论文一开始用pix2pix尝试合成更高分辨率的图片,但发现效果不好,训练也很不稳定。所以就对pix2pix进行了一顿魔改。我们来看看他们是怎么改进的。由粗到精的G网络

DCD_LIN的博客 1万+

【数据结构】递归程序的非递归实现

用递归代码实现斐波那契数列求解,利用转换规则(不简化) 将递归代码转换为非递归代码。(C++) 求1+2+3+…+n的和: 递归做法 int sum(int n) { if (n == 0) return 0; else { return n + sum(n - 1); } } 非递归的实现 #include<iostream> using namespace std; #include<stack> int sum(int n) {//非递归 i

清风微醺的博客 970

ElementUI中的el-table解决宽度问题 - 根据内容自动撑开

在使用element-ui中,会发现表格组件el-table在未指定宽度情况下,会自动计算并给表格宽度赋值。但实际开发中,有时需要根据内容实际长度自动撑开显示,由内容的多少而决定表格的宽度,而不是默认宽度为100%。在默认情况下表格宽度为100%显示,并且列项未指定宽度情况下,剩余部分会平均分配宽度,本案例实际需求是由内容自动撑开显示。componentUpdated

觉醒法师的专栏 1万+

从零拆解快手Web端__NS_hxfalcon:JS逆向签名参数定位与复现

在JS逆向与前端反爬攻防中,签名参数总是绕不开的核心环节。无论是接口加密还是请求签名,其本质都是通过在客户端收集环境信息、时间戳与业务参数,经特定算法计算后生成用于服务端校验的动态令牌。理解这类参数的生成原理,不仅能提升逆向分析效率,也能帮助前端开发者更好地设计自身接口防护方案。在实际工程中,面对经Webpack打包且高度混淆的代码,直接全局搜索参数名往往难以奏效,需要结合请求抓包、调用栈跟踪、环境适配等方法逐步定位。此类签名参数广泛存在于现代Web应用的GraphQL或REST接口中,是接口数据安全的重要

weixin_29474431的博客 337

数据结构 实验报告09

一、实验目的和要求 目的:熟悉递归的深层逻辑并动手实现 要求:同实验01 二、实验环境 编译器:Vscode +DevC++ 系统:Windows10 CPU:i5-8265U@1.60GHz 三、实验内容 (1)用递归代码实现n!求解。 (2)利用转换规则(不简化) 将代码(1)转换为非递归代码。 (3)简化并梳理代码(2)的流程。 (4)用以上三个独立模块,测试6!的计算...

zRNA__的博客 950

XCP实战系列介绍09-基于Vehicle Spy进行XCP测量步骤详解

详细介绍如何使用Vehicle Spy进行XCP测量

initiallizer的博客 1393

如何用栈实现递归与非递归的转换

http://bbs.chinaunix.net/viewthread.php?tid=331522   http://www.cnblogs.com/SuperXJ/archive/2010/09/26/1836155.html   递归计算向非递归计算转换模板-转自http://mingliangfeng.iteye.com/blog/201084   最近由于工作上的需要,研究了...

我不当菜鸟 1680

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

[回溯法_八皇后]堆栈实现的非递归版本

[回溯法_八皇后]堆栈实现的非递归版本                                                                                                                By EmilMatthew                                                       

3126

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

平铺数组转树结构,递归和非递归

第二次for,根据parent来给元素的children里面来追加自身,如果没有parent就直接给目标数组push自身。树转扁平数组就比较点的,深度遍历,浅拷贝后把children删除后push进入数组就行,保留原有的name和pid。第一次for,新建个map,给每个数组元素都建立id=》item,递归往往让事情变得非常的缠绕,非必要情况不要使用递归。

小漠007的专栏 333

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

二叉树的非递归遍历

非递归实现二叉树的前序/后序/中序遍历 中序遍历 // arr[1] // arr[2] arr[3] // arr[4] arr[5] arr[6] // arr[7] arr[8] 如上数据, ...

weixin_30341735的博客 70

<转> - 归并排序(递归实现+非递归实现+自然合并排序)

来源 : http://www.cnblogs.com/liushang0419/archive/2011/09/19/2181476.html 归并排序的确是分治思想的经典代表。写了很多次,这次又有新的收获,过去用的是递归的实现方式,理论上任何用递归方法实现的代码都可以转换为非递归的形式,所以此例也不例外。然后再用非递归的实现方法上进行改进,完成了“自然归并”算法,这比直接归并效率要高一些...

weixin_30520015的博客 106

算法与数据结构09:二叉树

拿一张纸条,对折N次,然后从上往下,打印折痕的方向,折痕向下,打印down,折痕向上,打印up。

weixin_43889578的博客 192

数据结构-算法学习C++(入门)

按照递归序,上述顺序为:1,2,4,4,4,2,5,5,5,2,1,3,6,6,6,3,7,7,7,3,1;但是某些问题使用硬计算类的算法,可能会让计算的复杂度较高(大厂算法和数据结构笔试、面试题、acm比赛或者和acm形式类似的比赛,考察的都是硬计算类算法)上述是对三种排序算法的检测,如果报错可通过调整数组长度和数据大小,选择容易的数组进行测验,以解决报错。请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。时间复杂度O(n),额外空间复杂度O(h),h是二叉树的高度;

weixin_63685622的博客 1636

实用算法的分析与程序设计——递归法(实例,代码)(划分问题、0-1背包问题)

设有一个未知函数f,用其自身构成的已知函数g来定义:f(n)=g(n,f(n-1)) n>0 f(0)=a n=0为了定义f(n)必须f(n-1)……用自身的简单情况来定义自己的方式称为递归定义一个递归定义必须是有确切含义的,也就是说,必须一步比一步简单,最后是有终结的,决不能无限循环下去。在f(n)的定义中,当n为0时定义一个已知数a,是最简单的情况,称为递归边界,它本身不再使用

梦里水乡的专栏 1810

递归法应用背包问题C语言课程设计,实用算法的分析与程序设计——递归法(实例,代码)(划分问题、0-1背包问题)...

设有一个未知函数f,用其自身构成的已知函数g来定义:f(n)=g(n,f(n-1)) n>0 f(0)=a n=0为了定义f(n)必须f(n-1)……用自身的简单情况来定义自己的方式称为递归定义一个递归定义必须是有确切含义的,也就是说,必须一步比一步简单,最后是有终结的,决不能无限循环下去。在f(n)的定义中,当n为0时定义一个已知数a,是最简单的情况,称为递归边界,它本身不再使用递归的定义...

weixin_29826879的博客 426

630页!熬夜整理出的“高分宝典“:算法+数据结构+网络+操作系统

分享Java技术文以及学习经验也有一段时间了,实际上作为程序员,我们都清楚学习的重要性,毕竟时代在发展,互联网之下,稍有一些落后可能就会被淘汰掉,因此我们需要不断去审视自己,通过学习来让自己得到相应的提升。 近段时间,我也了解到很多小伙伴不清楚作为Java程序员应该掌握什么样的核心知识?实际上,那些老生常谈的Spring、Redis我也就不再去重复了。所以花了一个星期,整理了这份630页的"高分宝典",主要涉及算法、数据结构、网络、操作系统等几个部分,以及我个人的一些面试经历,希望能够对大家提升自己有所帮

javassb的博客 1247

浅谈尾递归 转自豆瓣God-Mode

浅谈尾递归 2013-02-10 14:12:57 在《数据结构与算法分析:C描述》(Data Structures and Algorithm Analysis In C)的第三章中,以打印链表为例,提到了尾递归(tail recursion)并指出了尾递归是使用递归极其不当的例子,它指出虽然编译器会对尾递归自动优化,但即便如此最好还是不要去写尾递归。而我在《算法精解:C语言描述

tom555cat 782
上一篇: list中使用merge()函数报错squence not orderd
下一篇: pytorch中torch.stack()函数总结
RealWeakCoder
博客等级 码龄7年 236粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值