Why This Matters
Every time you press undo, your editor pops the last action off a stack. Every time a function calls another function, the runtime pushes a frame onto the call stack. Stacks are everywhere in computing, and their simplicity is their power: you can only add to the top and remove from the top.
This Last-In-First-Out constraint makes stacks ideal for tracking nested state, reversing sequences, and solving problems where the most recent item matters most. Once you recognize the stack pattern, you will see it in compilers, browsers, operating systems, and everyday algorithms.
Define Terms
Visual Model
The full process at a glance. Click Start tour to walk through each step.
A stack: Last In, First Out (LIFO). Push adds to the top, pop removes from the top. Both O(1).
Code Example
// Stack implementation using an array
class Stack {
constructor() {
this.items = [];
}
push(value) {
this.items.push(value);
}
pop() {
if (this.isEmpty()) throw new Error("Stack underflow");
return this.items.pop();
}
peek() {
if (this.isEmpty()) throw new Error("Stack is empty");
return this.items[this.items.length - 1];
}
isEmpty() {
return this.items.length === 0;
}
get size() {
return this.items.length;
}
}
// Using a stack
const stack = new Stack();
stack.push("A");
stack.push("B");
stack.push("C");
console.log(stack.peek()); // "C"
console.log(stack.pop()); // "C"
console.log(stack.pop()); // "B"
console.log(stack.size); // 1
// Practical example: matching parentheses
function isBalanced(str) {
const stack = new Stack();
const pairs = { ")": "(", "]": "[", "}": "{" };
for (const ch of str) {
if ("([{".includes(ch)) {
stack.push(ch);
} else if (")]}".includes(ch)) {
if (stack.isEmpty() || stack.pop() !== pairs[ch]) {
return false;
}
}
}
return stack.isEmpty();
}
console.log(isBalanced("([]){}")); // true
console.log(isBalanced("([)]")); // false
console.log(isBalanced("(((")); // falseInteractive Experiment
Try these exercises:
- Create a stack, push 5 items, then pop them all. Notice the reverse order.
- Use a stack to reverse a string: push each character, then pop them all into a new string.
- Trace through the call stack when
function a() { b(); }andfunction b() { c(); }execute. - Try calling
pop()on an empty stack. What error do you get? - Test the parentheses matcher with:
"({[]})","((())", and"}{)".
Quick Quiz
Coding Challenge
Write a function called `isBalanced` that takes a string containing brackets and returns true if all brackets are properly balanced and nested, false otherwise. Handle three types of brackets: (), [], and {}. Non-bracket characters should be ignored.
Real-World Usage
Stacks power many critical systems:
- The call stack: Every running program uses a stack to track function calls. When a function returns, its frame is popped off.
- Undo/redo: Text editors push each action onto an undo stack. Pressing undo pops the last action and pushes it onto a redo stack.
- Browser back button: Visited pages are pushed onto a history stack. Going back pops the current page.
- Expression parsing: Compilers use stacks to evaluate mathematical expressions and validate syntax.
- Depth-first search: DFS algorithms use a stack (explicitly or via recursion) to explore graph paths.