Worked examples — Stack applications — balanced parentheses, infix-to-postfix, function call stack
This page is the exhaustive drill for the parent note Stack applications. We will not re-teach the ideas from zero — the parent did that. Instead we hunt down every awkward case the three algorithms can throw at you, so no exam or interview surprises you.
Before we start, one reminder in plain words, because we lean on it in every example:
The scenario matrix
Each algorithm has "obvious" cases and "sneaky" cases. Here is the full grid of what can go wrong. Every cell gets covered by a worked example below (the Ex# tells you which).
| # | Algorithm | Case class | What makes it tricky | Covered by |
|---|---|---|---|---|
| A | Balanced brackets | Empty string (degenerate) | Zero characters — is nothing balanced? | Ex1 |
| B | Balanced brackets | Closer before any opener | Stack empty when we try to pop | Ex1 |
| C | Balanced brackets | Leftover openers | Counts look fine but pile isn't empty | Ex2 |
| D | Balanced brackets | Crossing / wrong type | Top of stack ≠ matching opener | Ex2 |
| E | Balanced brackets | Deep valid nesting (limiting) | Many pushes, then all pops | Ex3 |
| F | Infix→Postfix | Left-associative equal precedence | Must pop the waiting operator | Ex4 |
| G | Infix→Postfix | Right-associative ^ |
Must NOT pop the equal operator | Ex5 |
| H | Infix→Postfix | Nested parentheses + mixed ops | Flush-to-( inside a bigger expression |
Ex6 |
| I | Infix→Postfix | Word problem (real world) | Translate English → infix → postfix → number | Ex7 |
| J | Call stack | Recursion unwinding (limiting depth) | Frames return in reverse order | Ex8 |
| K | Call stack | Exam twist: max stack depth | Count peak frames, not total calls | Ex9 |
Ex1 — Empty string & a lone closer (cells A, B)
The picture below shows the two piles side by side — one ends empty (green thumbs-up in your mind), one hits the red "empty-pile pop."

Ex2 — Leftover openers & a crossing (cells C, D)
Ex3 — Deep valid nesting, limiting behaviour (cell E)
Ex4 — Left-associative equal precedence (cell F)
Ex5 — Right-associative ^ (cell G)
Ex6 — Nested parentheses + mixed operators (cell H)
a * (b + c * d) - e to postfix.
Forecast: There is an inner * inside the parentheses and an outer * and -. Guess where each operator lands in the output.
| tok | action | stack | output |
|---|---|---|---|
a |
output | a |
|
* |
push | * |
a |
( |
push | * ( |
a |
b |
output | * ( |
a b |
+ |
push (nothing higher under the () |
* ( + |
a b |
c |
output | * ( + |
a b c |
* |
top + is lower precedence → don't pop; push |
* ( + * |
a b c |
d |
output | * ( + * |
a b c d |
) |
pop to output until (: pop *, pop +, discard ( |
* |
a b c d * + |
- |
top * higher precedence → pop *; then - vs empty → push |
- |
a b c d * + * |
e |
output | - |
a b c d * + * e |
| end | pop all | a b c d * + * e - |
- Inside the parentheses,
*outranks+, soc*dis built first (a b c d *), then+joins it. Why this step? Precedence inside a group works exactly like outside — the(just blocks anything below it from popping across the boundary. - The
)flushes everything down to its(. Why this step? A group must fully resolve before the surrounding operators act. - The outer
*(waiting since token 2) pops when-(lower) arrives. Why this step?-is weaker, so the stronger waiting*executes first.
Answer: a b c d * + * e -.
Verify: Let a=2, b=3, c=4, d=5, e=1. Infix: 2 * (3 + 4*5) - 1 = 2 * (3+20) - 1 = 2*23 - 1 = 45. Postfix 2 3 4 5 * + * 1 - → 4*5=20, 3+20=23, 2*23=46, 46-1=45 ✓.
Ex7 — Real-world word problem (cell I)
plus a ₹150 delivery fee, then apply a flat ₹50 discount." Turn it into an expression, convert to postfix, and evaluate. Forecast: Guess the final amount before doing the algorithm.
- Translate English → infix:
3 * 200 + 150 - 50. Why this step? "3 shirts at ₹200" is a product; "plus delivery" and "minus discount" are additions/subtractions at the same level. - Convert to postfix (using Ex4's left-assoc rule for
+/-):3→ out;*→ push;200→ out; stack*, out3 200.+arrives: top*is higher → pop*; push+. out3 200 *.150→ out. out3 200 * 150.-arrives: top+equal precedence, left-assoc → pop+; push-. out3 200 * 150 +.50→ out; end → pop-.3 200 * 150 + 50 -. Why this step? The+/-must chain left-to-right, so-pops the waiting+(the Ex4 trap).
- Evaluate postfix:
3*200=600,600+150=750,750-50=700.
Answer: ₹700.
Verify: Direct infix 3*200 + 150 - 50 = 600 + 150 - 50 = 700 ✓. Units: rupees throughout (a count × price/shirt gives rupees, added to a rupee fee, minus a rupee discount — dimensionally consistent).
Ex8 — Recursion unwinding (cell J)
sum(3) where sum(n) = 0 if n==0 else n + sum(n-1).
Forecast: Guess the return value and the order in which frames pop.
The figure shows frames pushed downward, then popping upward with their returned values.

sum(3)callssum(2)callssum(1)callssum(0)— four frames pushed. Why this step? Each call pauses to wait for the deeper call; a paused function's frame stays on the pile.sum(0)hits the base case, returns0first (it was pushed last). Why this step? LIFO — the last frame added is the first removed.- Unwind:
sum(1)=1+0=1,sum(2)=2+1=3,sum(3)=3+3=6. Why this step? Each frame resumes at itsn + (…)exactly where it paused, using the returned value.
Answer: sum(3) = 6; pop order is sum(0), sum(1), sum(2), sum(3) — reverse of push order.
Verify: sum(3) = 3+2+1+0 = 6 ✓ (the triangular number ). See Recursion and the Call Stack for the general frame mechanics.
Ex9 — Exam twist: peak stack depth (cell K)
f(n) calls g(n) twice in sequence (not nested): f(n){ g(n); g(n); } and g calls no one. If main calls f once, what is the maximum number of frames alive at any instant?
Forecast: There are 1 + 1 + 2 = 4 calls in total. Guess the peak depth — it is not 4.
- Timeline of pushes/pops:
mainpushed (depth 1).maincallsf→ pushf(depth 2).fcalls firstg→ pushg(depth 3),greturns → pop (back to depth 2).fcalls secondg→ pushg(depth 3), returns → pop (depth 2).freturns → pop (depth 1).mainreturns → pop (depth 0). Why this step? The twogcalls are sequential, not nested — the firstgfully returns (pops) before the second is pushed.
- The highest the pile ever reaches is 3 (
main,f, oneg). Why this step? Peak depth counts frames simultaneously alive, which depends on nesting, not the total call count (echoing Ex3's depth-vs-length lesson).
Answer: Maximum depth = 3, even though 4 calls happen in total.
Verify: Total distinct calls = 1(main) + 1(f) + 2(g) = 4; peak simultaneous frames = 3. They differ precisely because sibling calls reuse the freed space — the same reason [](){} (Ex3) has depth 1 despite 3 pairs.
Recall Quick self-test across all cells
Empty string "" — balanced? ::: Yes — no unfulfilled promises, stack ends empty.
Why does ([)] fail even with matched counts? ::: The closer ) pops [, which does not match — order/nesting is wrong.
Postfix of a - b + c? ::: a b - c + (pop the equal-precedence left-assoc -).
Postfix of 2 ^ 3 ^ 2? ::: 2 3 2 ^ ^ (right-assoc, do NOT pop the equal ^).
Postfix of a * (b + c * d) - e? ::: a b c d * + * e -.
Peak frames when main→f→(g;g) with g a leaf? ::: 3 (sibling g calls are sequential, not nested).
"Same level? Pop for plus-minus, keep for power." Left-associative + - * / pop an equal top; right-associative ^ keeps it.
Connections
- Stack — ADT and Implementation — the push/pop/peek used in every trace above.
- Operator Precedence and Associativity — the rule that Ex4 and Ex5 hinge on.
- Postfix Evaluation Algorithm — how the "Verify" steps re-run the RPN with one stack.
- Recursion and the Call Stack — Ex8's frame unwinding in general.
- Expression Trees and Evaluation — an alternative view of the same precedence structure.
- Queues — contrast: FIFO would break every LIFO argument here.