定义

栈是一种只能在顶端插入和删除的列表。顶端是指最后一个操作的元素,数组中指下标最大的元素,链表中指末尾的元素。所以栈是一种LIFO(后进先出)的数据结构。

实现

栈可以使用数组、链表两种方式实现。自己动手coding,可以学习怎么处理异常,还有一些其他细节。上一篇中分析到如果在表的末端插入和删除都是O(1)的时间复杂度。
栈的基本操作有:

E push(E item);
E pop();
E peek();
boolean empty();
int search(Object o);
int size() ;

应用

栈的常用在 1 代码编辑器检查语法错误;2 计算器实现;3 计算机函数递归调用。

代码语法检查

写代码过程中有”(“必定有”)”,有”[“必定有”]”。这些是平衡符号。实现这个功能的过程中用到栈。思路是这样的:
做一个空栈,读入字符一直到文件结尾。
如果字符是一个封闭符号(])}),则当栈空时报错。否则将栈元素弹出。如果弹出的符号不是对应的开放符号,则报错。
在文件结尾,如果栈非空则报错。
时间复杂度:线性的,与输入的字符串长度有关系。

计算器应用

例如写一个计算器实现:4.99*1.06+5.99+6.99*1.06,不同计算器给出的答案可能不同,可能是18.69或者19.37。在正确的计算过程中计算顺序是
01 4.99*1.06=A1;
02 A1+5.99=A1;
03 6.99*1.06=A2;
04 A1+A2=答案
这种操作的顺序书写出来:4.99 1.06 * 5.99 + 6.99 1.06 * +。这叫做后缀表达法或者逆波兰记法。4.99*1.06+5.99+6.99*1.06 这种表示方法叫做中缀表达式

如何从中缀到后缀?
假设输入的字符串是表达式合法的,可以使用栈,实现中缀到后缀的转换。例如中缀表达式为:a+b*c+(d*e+f)*g。这里有两个站,一个是输出栈,一个是符号栈。
01 读到一个操作数,push到输出栈;
02 读到一个操作符,push到符号栈;如果符号是”)”,则弹出符号栈元素到输出栈,直到碰到”(“,”(“弹出,不进入输出栈。如果是其他操作符号(例如:+-*/),从符号栈中弹出元素直到发现优先级更低的元素为止。对于”(“,”)”要特殊对待。
03 读到输入的末尾,把符号栈所有元素弹出,放入输出栈。

方法调用

在计算机中,当从方法A执行一段,调用方法B,执行B之后,返回A继续执行。当然可能会嵌套多层方法调用。每一次方法跳出,都需要把当前执行状态记录到栈中。保存的信息称为活动记录。当方法调用太多的时候就会发生栈溢出的错误。这种保存是计算机主动帮我们做的。解决栈溢出,首先检查代码逻辑,是否忘记了基本情况判断;其次,如果真的是因为数据量太大,必须进行多次递归调用,则可以显示的使用栈,将递归改为递推,当然要损失的是代码的可读性。

代码任务

01 栈的数组实现
02 栈的链表实现
03 语法检查工具
04 计算器,中缀到后缀,后缀计算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值