- 1、本文档共61页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第章栈和队列概要
下面给出三个盘子搬动时hanoi(3, A, B, C) 递归调用过程, 如图3.5所示。 hanoi(2,A,C,B): hanoi(1,A,B,C) move(A-C) 1号搬到C move(A-B) 2号搬到B hanoi(1,C,A,B) move(C-B) 1号搬到B move(A-C) 3号搬到C hanoi(2,B,A,C): hanoi(1,B,C,A) move(B-A) 1号搬到A move(B-C) 2号搬到C hanoi(1,A,B,C) move(A-C) 1号搬到C 图3.5 Hanoi塔的递归函数运行示意图 递归的优点 通过上面的例子可看出,递归既是强有力的数学方法, 也是程序设计中一个很有用的工具。其特点是对递归问题描述简捷,结构清晰,程序的正确性容易证明。 递归算法求解问题的要素 递归算法就是算法中有直接或间接调用算法本身的算法。 递归算法的要点如下: (1) 问题具有类同自身的子问题的性质,被定义项在定义中的应用具有更小的尺度。 (2) 被定义项在最小尺度上有直接解。 设计递归算法的方法是: (1) 寻找方法,将问题化为原问题的子问题求解(例n!=n*(n-1)!)。 (2) 设计递归出口,确定递归终止条件(例求解n!时,当n=1时,n! =1)。 递归算法到非递归算法转换 递归算法具有两个特性: (1) 递归算法是一种分而治之、把复杂问题分解为简单问题的求解问题方法,对求解某些复杂问题,递归算法的分析方法是有效的。 (2) 递归算法的时间效率低。 1) 消除递归的原因 其一:有利于提高算法时空性能,因为递归执行时需要系统提供隐式栈实现递归,效率低且费时。 其二: 无应用递归语句的语言设施环境条件,有些计算机语言不支持递归功能,如FORTRAN语言中无递归机制 。 其三:递归算法是一次执行完,这在处理有些问题时不合适,也存在一个把递归算法转化为非递归算法的需求。 2) 简单递归消除 在简单情况下,将递归算法可简化为线性序列执行,可直接转换为循环实现。 递归进层三件事: 保存本层参数、 返回地址; 传递参数,分配局部数据空间; 控制转移。 递归退层三件事: 恢复上层; 传递结果; 转断点执行。 尾递归 是指递归调用语句只有一个,而且是处于算法的最后。我们以阶乘问题的递归算法Fact(n)为例讨论尾递归算法的运行过程。为讨论方便,我们列出阶乘问题的递归算法Fact(n),并简化掉参数n的出错检查语句,改写递归调用语句的位置在最后,算法如下: long Fact(int n) { if(n==0) return 1; return n * Fact(n-1); } 图3.6 递归调用变化情况示意 图3.7 f(3)递归调用流程变化示意 由图3.7可看出,整个计算包括自上而下递归调用进层和自下而上递归返回退层两个阶段,所有递归调用直接或间接依赖f(0),所以整个阶段分两步,计算顺序在第二阶段,先计算f(0)→f(1)→…→f(n),工作变量y记录中间结果。 循环结构的阶乘问题算法Fact(n)如下: long Fact(int n) { int fac=1; for(int i=1;i=n;i++) /*依次计算f(1), …, f(n)*/ fac=fac* i; /* f(i)= f(i) * i */ return fac; } 3.4 队 列 3.4.1 队列的定义 队列(Queue):具有一定操作约束的线性表 ?插入和删除操作:只能在一端插入(队尾),而在另一端删除(队头)。 数据插入:入队列 数据删除:出队列 先来先服务 先进先出:FIFO 数据元素:可以是任意类型的数据,但必须属于同一个数据对象。 关系: 队列中数
文档评论(0)