Stacks & Queues
Stack Applications
Balanced brackets, infix to postfix conversion and postfix evaluation — the three stack algorithms every CSE 102 exam asks you to trace.
1. Balanced brackets
Every opening bracket must be closed by the matching bracket in the right order. Push each opener; on each closer, pop and check it matches.
#include <stdio.h>
int isBalanced(const char *s) {
char st[100];
int top = -1;
for (int i = 0; s[i]; i++) {
char c = s[i];
if (c == '(' || c == '[' || c == '{') st[++top] = c;
else if (c == ')' || c == ']' || c == '}') {
if (top == -1) return 0; // closer with nothing open
char o = st[top--];
if ((c == ')' && o != '(') || (c == ']' && o != '[') || (c == '}' && o != '{')) return 0;
}
}
return top == -1; // anything left open?
}
int main(void) {
const char *tests[] = {"{[a+b]*(c-d)}", "([)]", "((x)", "a[i] = (b + c) * {d}"};
for (int i = 0; i < 4; i++)
printf("%-22s %s\n", tests[i], isBalanced(tests[i]) ? "balanced" : "NOT balanced");
return 0;
}{[a+b]*(c-d)} balanced
([)] NOT balanced
((x) NOT balanced
a[i] = (b + c) * {d} balancedInfix, prefix and postfix
| Notation | Operator position | A + B * C |
Needs brackets? |
|---|---|---|---|
| Infix | between operands | A + B * C |
yes, plus precedence rules |
| Prefix (Polish) | before operands | + A * B C |
no |
| Postfix (Reverse Polish) | after operands | A B C * + |
no |
Computers prefer postfix: it can be evaluated left to right with one stack and no precedence rules.
2. Infix to postfix (shunting-yard)
Scan the infix expression left to right:
- Operand → write it to the output.
(→ push it.)→ pop to the output until the matching(; discard both brackets.- Operator → while the stack top is an operator of higher precedence, or equal precedence and left-associative, pop it to the output. Then push the new operator.
- At the end, pop everything left to the output.
Precedence: ^ (highest, right-associative) > * / > + -.
#include <stdio.h>
#include <ctype.h>
int prec(char op) {
if (op == '^') return 3;
if (op == '*' || op == '/') return 2;
if (op == '+' || op == '-') return 1;
return 0;
}
void toPostfix(const char *in, char *out) {
char st[100];
int top = -1, k = 0;
for (int i = 0; in[i]; i++) {
char c = in[i];
if (isalnum((unsigned char)c)) out[k++] = c;
else if (c == '(') st[++top] = c;
else if (c == ')') {
while (top >= 0 && st[top] != '(') out[k++] = st[top--];
top--; // discard '('
} else if (prec(c)) {
while (top >= 0 && st[top] != '(' &&
(prec(st[top]) > prec(c) || (prec(st[top]) == prec(c) && c != '^')))
out[k++] = st[top--];
st[++top] = c;
}
}
while (top >= 0) out[k++] = st[top--];
out[k] = '\0';
}
int main(void) {
const char *exprs[] = {"A+B*C", "(A+B)*C", "A+B*C-D/E", "A*(B+C)/D", "A^B^C", "(A-B/C)*(A/K-L)"};
char post[100];
for (int i = 0; i < 6; i++) {
toPostfix(exprs[i], post);
printf("%-18s -> %s\n", exprs[i], post);
}
return 0;
}A+B*C -> ABC*+ (A+B)*C -> AB+C* A+B*C-D/E -> ABC*+DE/- A*(B+C)/D -> ABC+*D/ A^B^C -> ABC^^ (A-B/C)*(A/K-L) -> ABC/-AK/L-*
Tracing A+B*C-D/E
| Symbol | Action | Stack | Output |
|---|---|---|---|
| A | output | A | |
| + | push | + | A |
| B | output | + | AB |
| * | higher than +, push | + * | AB |
| C | output | + * | ABC |
| - | pop * and + (≥ precedence), push - |
- | ABC*+ |
| D | output | - | ABC*+D |
| / | higher than -, push | - / | ABC*+D |
| E | output | - / | ABC*+DE |
| end | pop all | ABC*+DE/- |
3. Evaluating postfix
Scan left to right. Push numbers. On an operator, pop two values — the first pop is the right operand — apply the operator and push the result.
#include <stdio.h>
#include <ctype.h>
int evalPostfix(const char *s) {
int st[100], top = -1;
for (int i = 0; s[i]; i++) {
char c = s[i];
if (c == ' ') continue;
if (isdigit((unsigned char)c)) {
int num = 0;
while (isdigit((unsigned char)s[i])) num = num * 10 + (s[i++] - '0');
i--;
st[++top] = num;
} else {
int b = st[top--], a = st[top--]; // b is popped first: the right operand
switch (c) {
case '+': st[++top] = a + b; break;
case '-': st[++top] = a - b; break;
case '*': st[++top] = a * b; break;
case '/': st[++top] = a / b; break;
}
}
}
return st[top];
}
int main(void) {
printf("2 3 1 * + 9 - = %d\n", evalPostfix("2 3 1 * + 9 -"));
printf("6 2 / 3 - = %d\n", evalPostfix("6 2 / 3 -"));
printf("10 2 8 * + 3 - = %d\n", evalPostfix("10 2 8 * + 3 -"));
return 0;
}2 3 1 * + 9 - = -4 6 2 / 3 - = 0 10 2 8 * + 3 - = 23
Trace of 2 3 1 * + 9 -: push 2, 3, 1 → * pops 1 and 3, pushes 3 → + pops 3 and 2, pushes 5 → push 9 → - pops 9 and 5, pushes 5 − 9 = −4.
Prefix evaluation
Prefix works the same way but scanning right to left, and the first value popped is the left operand. Example: - + 2 * 3 1 9 evaluates to (2 + 3 × 1) − 9 = −4.
Test yourself
4 questions · pick an answer to check it instantly
- 1
What is the postfix form of
(A + B) * (C - D)?Each bracketed part becomes its own postfix group, followed by*. - 2
Evaluate the postfix expression
5 1 2 + 4 * + 3 -.1 + 2 = 3; 3 × 4 = 12; 5 + 12 = 17; 17 − 3 = 14. - 3
Which string is not balanced?
In([)],)arrives when[is on top of the stack. - 4
Why is postfix easier for a computer to evaluate than infix?
Postfix encodes the order of operations in the order of the symbols.