栈是能描述和实现的最简单的集合
栈是线性的集合,访问都严格地限制在一端(顶top),后进先出(LIFO)
放入项 | 压入(push) |
删除项 | 弹出(pop) |
具体应用:
1 将中缀表达式转换为后缀表达式,并计算后缀表达式
2 回溯算法
3 管理计算机内存以支持函数和方法的调用
4 支持文本编辑器、电子表格等的撤销功能
5 维护web浏览器所访问过的链接的历史记录
栈的三种应用
1 计算算术表达式
中缀形式 | 每个运算符位于两个运算数之间 | (34+22)*2 |
后缀形式 | 运算符紧跟在其运算数之后 | 34 22 + 2 * |
两种运算方式中运算数出现的顺序相同
后缀形式不需要括号:只要遇到运算符就应用
计算后缀表达式:
1 从左到右遍历表达式
2 遇到第一个运算符时对之前的两个运算数应用该运算符,并用结果替换这两个数和运算符
3 继续遍历直至末尾,只剩下值
Token(标记)==>一个运算数或运算符
将中缀表达式转化为后缀表达式:
1 有一个空的后缀表达式和一个空的栈,栈用来保存运算符和左圆括号
2 从左向右扫描中缀表达式
3 遇到一个运算数时,将其添加到后缀表达式
4 遇到一个左圆括号时压入栈中
5 遇到一个运算符,从栈中弹出和它具有相等的或更高等级的运算符,添加至后缀表达式末尾,将扫描到的运算符压入栈中
6 遇到一个右圆括号,将运算符从栈中移动到后缀表达式中,直到遇到了与之匹配的左圆括号,并将其丢弃
7 遇到中缀表达式结束时,将栈中剩余运算符转移到后缀表达式中
2 回溯算法
从一个预定义的起始状态开始,随后从一个状态移动到另一个状态,以搜索想要的最终状态
两种主要的实现方式: 栈; 递归
3 内存管理
Python的编译器将Python程序转换为字节码,Python虚拟机会执行这些字节码
PVM所控制的内存或运行时的环境被划分为6个区域
PVM有两个内部变量, locationCounter(指向PVM下一步将要执行的命令)和basePtr(指向基本活动记录的顶部)
使用栈
栈并非Python的内建模型,可用列表来模拟,但额外的操作违背了栈的本意
故 为栈定义一组更严格的接口
栈接口
Push, pop, peek(查看栈顶部元素)
栈类型同样包括isEmpty,clear, len, str, in, +操作,加一个迭代器
pop,peek先验条件:顶部元素存在,否则error
示例:匹配括号
[ ( ] ) 不正确嵌套和缺项都会抛出错误
思路:
1 将开始的括号压入栈中
2 遇到一个结束括号时,若栈为空,或找到的栈顶不是相同类型的开始括号,不匹配
3 若是正确类型的,就从栈顶弹出一项,继续扫描
4 到了表达式末尾,栈应当为空,若非空,则括号不匹配
数组/链表(ArrayStack, LinkedStack)
开发测试程序
总结:
1 栈是线性的集合,只允许从一端访问,叫做栈顶
2 栈上的其他操作:查看顶部元素、确定元素数目、判断栈是否为空、返回一个字符串表示
3 先进后出的方式管理数据项(应用:匹配括号,计算后缀表达式、回溯算法、为虚拟机子例程调用管理内存)
4 数组和单链表结构支持栈的简单实现