当前课程知识点:数据结构(上) > 第四章 栈与队列 > (c4)栈应用:中缀表达式求值 > 04C4−6A 实例A
好,让我们来通过一个实例
具体了解如何利用栈结构
实现中缀表达式的求值
这是我们待求值的中缀表达式
在我们算法中
需要用到一个操作符栈
以及一个操作数栈
而且如我们所约定的
在最开始的时候
我们首先要将表达式的结束字符\0
在这里以$表示
首先铺垫在操作符栈中
以下只不过是一个
线性扫描的迭代过程
我们首先将注意力放在
第一个字符,也就是左括号上
作为一个操作符
它需要与操作符栈的
当前栈顶\0进行比较
查阅优先级表会发现
是一个小于号
这等效于左括号优先级比\0要更高
因此按照算法的流程,我们应该将
这个优先级更高的操作符
推入操作符栈中
暂时缓存起来,也就是这样
此后我们随即
将注意力转向下一个字符
我们看到这是一个操作数
这种处理我们讲过是非常简明的
也就是直接令这个操作数
进到操作数栈中去
对应的结果应该是这样
同样地,接下来
把注意力放到下一个字符
运算符加号
同样地,它要与当前的栈顶
也就是左括号比较优先级
如果你手头有那张优先级表的话
会发现依然是一个小于号
所以我们的处理手法是一样的
再一次令当前的这个操作符
进到操作符栈中去
做一次push操作
同时将注意力转向下一个字符
又是一个操作数
所以依然非常简明,将它
push到它所对应的操作数栈中去
也就是变成这样
同样,我们将注意力转向下一个字符
这是一个运算符
在我们这里约定
它代表的是乘方
同样,查阅优先级表
乘方相对于当前的栈顶加法
优先级更高
所以依然是简明的push操作
接下来,我们关注的下一个字符
依然是一个操作数
同样,让它进到操作数栈中去
下一个字符是阶乘运算符
同样,经过查表会发现
阶乘的优先级更高
所以还是我们刚才
所说的那种处理手法
也就是令新遇到的这个
阶乘运算符入栈
好,再接下来,我们又碰到一个
运算符减号
查表会发现
第一次碰到了另一种情况
也就是大于号
换而言之,这个时候是反过来
栈顶运算符的优先级
相对于当前这个运算符要更高
我们讲过,这意味着,此前缓存在栈中的
这个栈顶运算符已经等到了
它可以执行的时机
因此阶乘号将被弹出,3也将被弹出
而它们的运算结果6
将重新回到栈中
结果应该是这样
请注意,这个时候我们的关注力
依然在刚才仍未处理完的
减法运算符上
这个当前的减法运算符
依然要与新的栈顶运算符
也就是乘方号,继续比较优先级的次序
那么我们查表会发现
依然是一个刚才那样的大于号
同样,这意味着此前缓存
和保留起来的这个乘方运算符,也等到了
它可以执行的时机
因此接下来,它也需要从操作数栈中
去索取对应数目,也就是两个运算数
并且执行乘方运算
所以接下来,应该是乘方号出栈
6和2也会出栈
而它们运算的结果
2的6次方将会重新纳入到
操作数栈中
注意,我们依然停留在
仍未处理完毕的减法运算符上
因此接下来,继续将它
与新栈顶运算符加法
进行优先级的比较
再一次地查表,同样是一个大于号
也就是说,此前所缓存起来的加法运算
已经等到了应该执行的时机
因此加法运算符将会出栈
而同时,操作数栈中的
64和1也会相继出栈
并且执行加法运算
它们的和,也就是65,将会重新入栈
也就是这样
我们注意到关注点仍然停留在减法上
因此再一次地,我们仍需要
将减法运算符
与栈顶的左括号运算符
进行优先级的比较
我们会发现它又重新回到了
小于的情况
也就是说,这等效于
减法运算符的优先级更高
因此按照算法设计的流程
这个时候应该令
当前的这个运算符入栈
转入这样的一个状态
接下来,我们关注的位置处
又重新是一个操作数
这是非常简明的一种情况
我们说过,所有的操作数遇到之后
都是直接令它进入到操作数栈中去
因此我们接下来会转入到
这样一个状态
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验