Stacks in DSA: LIFO, Real Use Cases & Implementation
Last modified - 18-08-2026
Author - Krishna Shinde
If you're working through a DSA tutorial or any set of data structures tutorials for beginners, the stack is usually one of the first structures you meet after arrays and linked lists. It looks almost too simple to matter, one rule, one direction, and yet it quietly powers everything from your browser's back button to how function calls actually execute.
This stacks in DSA tutorial covers what a stack is, how LIFO ordering works, where stacks show up in real software, and how to implement one from scratch in C++, both with a plain array and with the STL stack container.
By the end of this data structures tutorial, you'll know exactly when to reach for a stack and how to build one without relying on a library.
Table of Contents
What Is a Stack?
A stack is a linear data structure that follows the LIFO principle, Last In, First Out. The last element you insert is the first one you remove. Think of a stack of plates: you place new plates on top, and you always take the top plate off first. You can't pull a plate out from the middle without disturbing everything above it.
A stack supports a small, fixed set of operations:
- push – add an element to the top
- pop – remove the element from the top
- peek / top – look at the top element without removing it
- isEmpty – check whether the stack has any elements left
That's it. No random access, no inserting in the middle. This restriction is exactly what makes a stack fast and predictable, every operation runs in O(1).

Implementing a Stack from Scratch (Array-Based)
Before reaching for a built-in stack, it helps to build one yourself so the mechanics are obvious.
Syntax (conceptual):
class Stack {
array of fixed size
topIndex (starts at -1)
push(value): topIndex++; array[topIndex] = value
pop(): value = array[topIndex]; topIndex--; return value
peek(): return array[topIndex]
isEmpty(): return topIndex == -1
}Example 1: Array-Based Stack in C++
#include <iostream>
using namespace std;
class Stack {
int arr[100];
int top;
public:
Stack() {
top = -1;
}
void push(int value) {
if (top == 99) {
cout << "Stack Overflow" << endl;
return;
}
arr[++top] = value;
}
void pop() {
if (top == -1) {
cout << "Stack Underflow" << endl;
return;
}
top--;
}
int peek() {
return arr[top];
}
bool isEmpty() {
return top == -1;
}
};
int main() {
Stack s;
s.push(10);
s.push(20);
s.push(30);
cout << "Top element: " << s.peek() << endl;
s.pop();
cout << "Top after pop: " << s.peek() << endl;
return 0;
}Output:
Top element: 30
Top after pop: 20Using the Built-In STL Stack in C++
Once you understand the mechanics, C++'s Standard Template Library gives you a ready-made stack so you don't have to manage the array and index yourself.
Syntax:
#include <stack>
stack<int> s;
s.push(value);
s.pop();
s.top();
s.empty();Example 2: STL Stack in Action
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
s.push(1);
s.push(2);
s.push(3);
while (!s.empty()) {
cout << s.top() << " ";
s.pop();
}
return 0;
}Output:
3 2 1Notice the order: even though 1 was pushed first, it comes out last. That's LIFO in action.
Real Use Cases of Stacks
Stacks aren't just an interview topic, they're running under the hood of tools you use every day.
Function Call Stack Every time a function calls another function, the program pushes a new "frame" onto the call stack, tracking local variables and the return address. When the function finishes, its frame is popped off and control returns to the caller. This is also why deep, unbounded recursion causes a stack overflow, the call stack runs out of space.
Undo Functionality Every "undo" button, in a text editor, an image tool, or an IDE, is a stack. Each action gets pushed as you perform it. Pressing undo pops the most recent action off and reverses it, one step at a time, in exact reverse order.
Browser History (Back Button) Each page you visit gets pushed onto a stack. Hitting the back button pops the most recent page and takes you there, this is why "back" always retraces your steps in reverse, never skipping ahead.
Expression Evaluation & Syntax Parsing Compilers and calculators use stacks to evaluate expressions and check for balanced brackets. Anytime you see an opening bracket, you push it, and a matching closing bracket pops it. If the stack isn't empty at the end, or you try to pop from an empty stack, the expression is invalid.
Example 3: Balanced Parentheses Check
#include <iostream>
#include <stack>
using namespace std;
bool isBalanced(string expr) {
stack<char> s;
for (char c : expr) {
if (c == '(' || c == '{' || c == '[') {
s.push(c);
} else if (c == ')' || c == '}' || c == ']') {
if (s.empty()) return false;
s.pop();
}
}
return s.empty();
}
int main() {
string expr = "{[()]}";
cout << (isBalanced(expr) ? "Balanced" : "Not Balanced") << endl;
return 0;
}Output:
BalancedStack vs Array vs Queue: Which Should You Use?
| Structure | Access Rule | Best Used When |
|---|---|---|
| Array | Any index, any time | You need random access to elements |
| Stack | Only the top (LIFO) | You need to reverse order, track history, or undo actions |
| Queue | Only the front (FIFO) | You need to process items in the order they arrived |
Advantages and Disadvantages of Stacks
Advantages:
- Simple to implement, whether array-based or with a library.
- All core operations run in constant time, O(1).
- Naturally models any "reverse order" or "most recent first" problem.
Disadvantages:
- No random access, you can't reach an element in the middle without popping everything above it.
- A fixed-size array implementation can overflow if not sized carefully.
Conclusion
The stack is proof that a data structure doesn't need a long list of operations to be powerful, it just needs the right one. Once you've implemented push, pop, peek, and isEmpty yourself, patterns like the call stack, undo history, and bracket matching stop feeling like separate topics and start looking like the same idea in different clothes.
Keep practicing by tracing through push and pop calls by hand, and try rewriting the balanced-parentheses check to also handle mismatched bracket types. We've already covered arrays and linked lists in this series, queues are up next. Follow Algoflame for more C++ tutorials and DSA content.