中缀表达式转后缀表达式: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+CBC 直接输出,+ 入栈。虽然 + 优先级低,但它被左括号保护,属于括号内表达式。

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';