DSA Stacks — LIFO Fundamentals Visualized
Learn stack fundamentals — LIFO push/pop/peek, O(1) operations, interactive step visualizer, code breakdown, and real-world undo/call-stack examples.
Introduction
Stacks are LIFO (Last In, First Out) structures — the last element pushed is the first one popped. Think of a stack of plates: you add and remove only from the top.
Built on arrays or linked lists, stacks power undo systems, call stacks, DFS, and bracket matching.
Quick index
| # | Section |
|---|---|
| 1 | How stacks work |
| 2 | Interactive visualizer |
| 3 | Full implementation |
| 4 | Complexity & use cases |
| 5 | Real-life examples |
1. How stacks work
top → [30]
[20]
[10]
bottom| Operation | Action | Result |
|---|---|---|
| push | Add to top | O(1) |
| pop | Remove from top | O(1) |
| peek | Read top, no remove | O(1) |
| isEmpty | Check if empty | O(1) |
2. Interactive visualizer
Stack — Fundamentals
LIFO structure — push and pop from the top only. Foundation for undo, call stacks, and DFS.
Stack starts empty — only top element is accessible.
Stack class
class Stack {
constructor() { this.items = [] }
push(val) { this.items.push(val) }
pop() { return this.items.pop() }
peek() { return this.items[this.items.length - 1] }
isEmpty() { return this.items.length === 0 }
}LIFO — Last In, First Out.
push / pop
O(1)
peek
O(1)
Order
LIFO
3. Full implementation
class Stack {
constructor() {
this.items = []
}
push(val) {
this.items.push(val)
}
pop() {
return this.items.pop()
}
peek() {
return this.items[this.items.length - 1]
}
isEmpty() {
return this.items.length === 0
}
}Function calls with output
// ── Demo calls — output shown on the right ──
const s = new Stack()
s.push(10) // → [10]
s.push(20) // → [10, 20]
s.push(30) // → [10, 20, 30]
s.peek() // → 30
s.pop() // → 30
s.pop() // → 20
s.isEmpty() // → false4. Complexity & use cases
| Metric | Value |
|---|---|
| push | O(1) |
| pop | O(1) |
| peek | O(1) |
| search | O(n) |
| Use case | Why stack |
|---|---|
| Undo/redo | Reverse last action |
| Call stack | Function returns in reverse call order |
| DFS traversal | Track path, backtrack by popping |
| Valid parentheses | Match opening/closing brackets |
5. Real-life examples
| Scenario | Stack role |
|---|---|
| Ctrl+Z undo | Each edit pushed; undo pops last action |
| Browser back stack | Pages pushed on navigate; back pops |
| Function call stack | Each call pushed; return pops frame |
| Syntax parsing | Opening tokens push; closing tokens pop and match |
Browser undo stack
Ctrl+Z in editors — each edit pushes to stack; undo pops the last action.
Document: "Hello"
undoStack: [type "Hello"]
First edit pushed onto undo stack.
Real-world implementation
class UndoStack {
constructor() { this.actions = [] }
push(action) { this.actions.push(action) }
undo() { return this.actions.pop() ?? null }
canUndo() { return this.actions.length > 0 }
}Full working code for the scenario above.
Function calls with output
| // ── Function calls with output ── | |
| const undo = new UndoStack() | |
| undo.push({ type: "insert", text: "Hello" }) | → stack depth 1 |
Side output shows return value after each call — step through to trace execution.
Summary
Stacks give O(1) push/pop at one end with LIFO ordering — essential for reversal, nesting, and backtracking.
Next reads: Stack Types · Stack Applications · DSA Queues
Subscribe to my newsletter
Stay up to date and get notified when I share new contents.
No spam ever, unsubscribe anytime