
👨💻 关于作者:会编程的土豆
"不是因为看见希望才坚持,而是坚持了才看见希望。"
你好,我是会编程的土豆,一名热爱后端技术的Java学习者。
📚 正在更新中的专栏:
-
《数据结构与算法》😊😊😊
-
《leetcode hot 100》🥰🥰🥰🤩🤩🤩
-
《数据库mysql》
💕作者简介:后端学习者
一文搞懂中缀表达式与后缀表达式(栈的经典应用,附完整代码)
在数据结构与算法中,"中缀 → 后缀 → 计算"的问题是栈的经典应用之一,不仅是考试高频,也是面试常考点。很多人一开始会觉得规则很多、过程很乱,其实本质非常清晰:用栈来处理运算符优先级。
这篇文章带你从零搞懂三件事:什么是中缀/后缀表达式;如何把中缀转后缀;如何计算后缀表达式。
一、三种表达式形式
1. 中缀表达式(我们平时写的)
3 + 4 * 2
特点:
-
运算符在中间
-
需要考虑优先级和括号
2. 后缀表达式(逆波兰表达式)
3 4 2 * +
特点:
-
运算符在后面
-
不需要括号
-
可以直接用栈计算
3. 前缀表达式(了解即可)
+ 3 * 4 2
这篇重点讲中缀和后缀。
二、为什么要转后缀?
中缀表达式难点在于:
-
有优先级(* 比 + 高)
-
有括号
而后缀表达式:
完全不需要优先级规则,直接算
所以思路是:
中缀表达式 → 转后缀 → 用栈计算
三、中缀转后缀(核心)
规则总结(一定要理解)
遍历中缀表达式:
-
遇到数字 → 直接输出
-
遇到运算符 →
-
栈空 → 入栈
-
栈顶优先级 ≥ 当前 → 弹出再入栈
-
-
遇到 '(' → 入栈
-
遇到 ')' → 一直弹到 '('
运算符优先级函数
int priority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
中缀转后缀完整代码
cpp
#include <iostream>
#include <stack>
using namespace std;
string infixToPostfix(string s) {
stack<char> st;
string result = "";
for (char c : s) {
if (isdigit(c)) {
result += c; // 数字直接输出
}
else if (c == '(') {
st.push(c);
}
else if (c == ')') {
while (!st.empty() && st.top() != '(') {
result += st.top();
st.pop();
}
st.pop(); // 弹出 '('
}
else { // 运算符
while (!st.empty() && priority(st.top()) >= priority(c)) {
result += st.top();
st.pop();
}
st.push(c);
}
}
while (!st.empty()) {
result += st.top();
st.pop();
}
return result;
}
举个例子
中缀:3+4*2
过程:
3 → 输出
+ → 入栈
4 → 输出
* → 入栈(优先级更高)
2 → 输出
最终:
后缀:342*+
四、后缀表达式计算
后缀表达式的计算更简单:
核心规则
-
遇到数字 → 入栈
-
遇到运算符 → 弹出两个数计算,再入栈
完整代码
cpp
#include <stack>
#include <iostream>
using namespace std;
int evaluatePostfix(string s) {
stack<int> st;
for (char c : s) {
if (isdigit(c)) {
st.push(c - '0');
}
else {
int b = st.top(); st.pop();
int a = st.top(); st.pop();
if (c == '+') st.push(a + b);
if (c == '-') st.push(a - b);
if (c == '*') st.push(a * b);
if (c == '/') st.push(a / b);
}
}
return st.top();
}
举个例子
后缀:342*+
计算过程:
3 → 入栈
4 → 入栈
2 → 入栈
* → 4*2=8 入栈
+ → 3+8=11
结果:
11
五、整体流程总结
中缀表达式
↓(栈)
后缀表达式
↓(栈)
最终结果
六、常见坑点
1. 弹栈顺序不能错
int b = st.top(); st.pop();
int a = st.top(); st.pop();
不是 a 和 b 随便写!
2. 忘记处理括号
遇到 ')' 一定要弹到 '('
3. 优先级判断写错
priority(st.top()) >= priority(c)
七、进阶方向
学完这一块,可以继续提升:
-
支持多位数(如 123)
-
支持负数
-
支持空格解析
-
直接计算中缀(不转后缀)
八、一句话总结
中缀难在"优先级",后缀强在"可直接计算",而栈就是连接两者的桥梁。