中缀表达式对应中序遍历,前缀对应前序遍历,后缀对应后序遍历。之所以可以转换,我想是因为:
- 标准的满二叉树,非多叉。
- 运算符优先级一定。
- 操作数均为叶子,操作符均为内部节点。
中缀转后缀
定义优先级:(, ) > *, / > +, - > 空栈
。
定义输出操作为:push back
- 构造一个空的运算符栈
- 对中缀表达式从左至右扫描,遇到操作数直接输出,遇到其它符号a处理如下
- 比较和栈顶符号b优先级大小,若a>b,则将a压入栈:此时说明当前运算符左侧表达式扫描完毕,但只存在不可输出的低优先级表达式
- 若
a<=b
,则将栈顶依次弹出,直到新的栈顶元素b’满足a>b’,再将a入栈:此时说明左侧表达式扫描完毕,且存在可以输出的相同或更高优先级表达式- 对于
)
,直到遇到(
,两个元素均弹出
- 对于
- 若扫描完毕,栈中仍有字符,依次输出
1 |
|
中缀转前缀
定义优先级:(, ) > *, / > +, - > 空栈
。
定义输出操作为:append_front
- 构造一个空的运算符栈
- 对中缀表达式从右至左扫描,遇到操作数直接压入结果栈,遇到其它符号a处理如下
- 比较和栈顶符号b优先级大小,若a>=b,则将a压入栈:此时说明
- 若
a<b
,则将栈顶依次弹出,直到新的栈顶元素b’满足a>=b’,再将a入栈:- 对于
(
,直到遇到)
,两个元素均弹出
- 对于
- 若扫描完毕,栈中仍有字符,依次输出
1 |
|
后缀转中缀
构造表达式树。
- 构造一个节点栈
- 从左向右扫描后缀表达式,如果遇到数字,构造叶子节点入栈。
- 如果遇到运算符,则弹出两个节点。后弹出的节点作为第一操作数,用运算符作为子树的根节点生成子树。再将根节点入栈。
前缀转中缀
构造表达式树。
- 构造一个节点栈
- 从右向左扫描前缀表达式,如果遇到数字,构造叶子节点入栈
- 如果遇到运算符,则弹出两个节点。先弹出的节点作为第一操作数,用运算符作为子树的根节点生成子树,再将根节点入栈。
参考
- https://blog.csdn.net/walkerkalr/article/details/22798365