栈与队列的深入讨论

1.中缀表达式转换成后缀表达式
在高级程序设计语言的编译软件里,就是用类似的转换算法对算数公式进行转换,最终将其转换成计算机可以直接执行的机器指令序列。
设计思路:
关键在于如何恰当地去掉中缀表达式的括号,在必要时按运算符的优先级调换运算符的次序。用栈存放表达式中的开括号和暂时不能确定次序的运算符。
实现:
在这里插入图片描述
在这里插入图片描述
做两道题试试
在这里插入图片描述

2.递归函数的实现
大多数程序设计语言运行环境所提供的函数调用机制是底层的编译栈支持的。运行时环境值得是目标计算机用来管理存储器并保存执行过程所需信息额寄存器及存储器的结构。

静态分配与动态分配
在这里插入图片描述
栈区域用于分配具有后进先出特征的数据,而堆用于存储其他类型的数据。
运行栈种元素的类型设计动态存储分配一个很重要的概念:函数活动记录
在这里插入图片描述
运行栈又叫作活动记录栈或者调用栈。
函数调用:
1.调用函数发送调用信息,包括调用方有要传送给被调方的信息,如传给形式参数。
在这里插入图片描述

3.改善递归的效率
递归的算法具有可读性强、结构简练、正确性易证明等优点,但在时空开销上较大,为提高算法的时空效率,尤其是在某些对响应时间十分敏感的实时应用环境下,或者不支持递归调用的程序环境下,须将递归算法转化为非递归算法,问题才能够有效解决。
a .尾递归
如果拿fib(6)=6+fib(5)作为例子的话,普通的递归算到最后,内存中需要储存6+5+4+3+2+fib(1),而尾递归则是20+fib(1)。前者耗费了大量内存。

本段复制粘贴

通常递归都是在栈上根据调用顺序依次申请空间进行运算,然后层层回调,这是基于上一层运算依赖于下一层的运算结果(或者说上一层的运算还没用做完,需要下一层返回的结果)。

而尾递归的情况是下层计算结果对上层==“无用”(上一层运算已经做完,不依赖后续的递归),为了效率,直接将下一层需要的空间覆盖在上一层上==。

所以,尾递归,比线性递归多一个参数,这个参数是上一次调用函数得到的结果

所以,关键点在于,尾递归每次调用都在收集结果避免了线性递归不收集结果只能依次展开消耗内存的坏处

使用尾递归可以带来一个好处:因为进入最后一步后不再需要参考外层函数(caller)的信息,因此没必要保存外层函数的stack,递归需要用的stack只有目前这层函数的,因此避免了栈溢出风险
————————————————
版权声明:本文为CSDN博主「Jeff_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40539125/article/details/88043983

b.迭代
阶乘、斐波那契数列
c .利用栈存取数据转变成非递归算法
在这里插入图片描述

4.栈和队列的进一步认识
栈的应用:记录网页访问历史、保存文本编辑器的undo序列、递归实现、深度优先搜索。
队列的应用:广度优先搜索、消息缓冲器、操作系统各种资源的管理队列。
1.顺序栈和链式栈的比较:
两者的基本操作的时间效率难分伯仲,基本差异也是顺序存储和链式存取的区别。顺序栈更方便访问栈中元素。顺序栈在实际中更常用一点。
2.多栈管理:(共享栈)
在管理使用多个栈时,当一个栈收缩,另一个栈增长时,这种方法很奏效。
利用栈和队列的思想可以设计出来一系列变种的栈和队列结构。STL提供的基本序列中就有双端队列deque,栈和队列是通过deque来实现的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值