中缀表达式转后缀表达式:A*(B+C)-D/(E-F)
1. 先输出 A,暂存 *
操作数直接进入后缀表达式。扫描到 * 时,右操作数还没有完整出现,所以 * 入运算符栈。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
A
运算符栈
*
if (isalnum(token)) {
postfix[outIndex++] = token;
} else if (IsOperator(token)) {
Push(&operatorStack, token);
}
2. 左括号作为栈内边界
扫描到 ( 时直接入栈。它把括号内的运算和外层 * 隔开,使括号内低优先级的 + 不会被外层运算提前影响。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
A
运算符栈
*(
遇到当前运算符时,只能和左括号之上的栈顶运算符比较优先级。
} else if (token == '(') {
Push(&operatorStack, token);
}
3. 括号内的 + 暂存
扫描到 B+C:B、C 直接输出,+ 入栈。虽然 + 优先级低,但它被左括号保护,属于括号内表达式。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
ABC
运算符栈
*(+
while (GetTop(operatorStack, &topOperator) &&
topOperator != '(' &&
Priority(topOperator) >= Priority(token)) {
Pop(&operatorStack, &topOperator);
postfix[outIndex++] = topOperator;
}
Push(&operatorStack, token);
4. 右括号触发括号内输出
扫描到 ) 时,连续弹出并输出运算符,直到遇到 (。括号本身只控制范围,不进入后缀表达式。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
ABC+
运算符栈
*
B+C 作为一个整体完成,后面才能成为外层 * 的右操作数。
} else if (token == ')') {
while (GetTop(operatorStack, &topOperator) &&
topOperator != '(') {
Pop(&operatorStack, &topOperator);
postfix[outIndex++] = topOperator;
}
Pop(&operatorStack, &topOperator);
}
5. 外层 - 使 * 先输出
扫描到 - 时,栈顶 * 优先级高于 -,所以先输出 *,再把 - 入栈。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
ABC+*
运算符栈
-
while (Priority(topOperator) >= Priority(token)) {
Pop(&operatorStack, &topOperator);
postfix[outIndex++] = topOperator;
}
Push(&operatorStack, token);
6. 第二组括号保护 E-F
扫描 D/(E-F) 时,/ 先入栈;进入括号后,E-F 在左括号之上处理。右括号到来时,- 先输出。
A
*
(
B
+
C
)
-
D
/
(
E
-
F
)
输出
ABC+*DEF-
运算符栈
-/
E-F 成为 / 的右操作数,不能先让外层 / 输出。
// 右括号只弹出左括号之上的运算符
while (topOperator != '(') {
Pop(&operatorStack, &topOperator);
postfix[outIndex++] = topOperator;
}
7. 扫描结束后清空运算符栈
输入处理完后,依次弹出剩余运算符。先输出 /,再输出外层 -。
输出
ABC+*DEF-/-
结果
ABC+*DEF-/-
while (Pop(&operatorStack, &topOperator)) {
postfix[outIndex++] = topOperator;
}
postfix[outIndex] = '\0';