Stack
Stack in Data Structures
Learn what a stack is, how stack works using the LIFO principle, important stack operations such as push, pop, peek, and isEmpty, and how stacks are used in real-world programming problems like undo, browser history, function calls, expression evaluation, and backtracking.
Introduction
A stack is an important linear data structure in programming. It stores data in a special order where the last item added is the first item removed. This rule is known as LIFO, which means Last In, First Out.
A stack is very useful when we need to manage data in reverse order. For example, when we use the undo option in a text editor, the most recent action is undone first. When we go back in browser history, the most recently visited page is usually opened first. These are common real-world examples of stack behavior.
Stacks are widely used in computer science because many internal operations of a program follow stack behavior. Function calls, recursion, expression evaluation, undo-redo systems, backtracking algorithms, and syntax checking all use stack concepts.
Simple Definition of Stack
A stack is a data structure where elements are inserted and removed from only one end, called the top of the stack.
In simple words:
- A stack stores multiple elements in order.
- Elements are added from the top.
- Elements are removed from the top.
- The last inserted element is removed first.
- The first inserted element is removed last.
- Stack follows the LIFO rule.
Why Do We Need Stack?
Stacks are needed when a program must remember the most recent operation and process it first. Many real-world and programming tasks require this type of behavior.
For example, if a user types text and makes several changes, the undo feature should reverse the latest change first. A stack is perfect for this because it stores actions in order and removes the most recent action first.
Without Stack
- Managing recent actions becomes difficult.
- Undo operations become harder to implement.
- Function call tracking becomes complex.
- Expression checking becomes harder.
- Backtracking problems become difficult to solve.
- Reverse-order processing becomes less organized.
With Stack
- Recent actions can be tracked easily.
- Undo operations become simple.
- Function calls can be managed systematically.
- Expression validation becomes easier.
- Backtracking can be implemented cleanly.
- Reverse-order processing becomes efficient.
Prerequisites
Before learning stacks, students should understand some basic programming and data structure concepts. These topics will make stack operations easier to understand.
| Prerequisite Topic | Why It Is Needed |
|---|---|
| Variables | To store stack values and top position. |
| Arrays / Lists | Stacks can be implemented using arrays or lists. |
| Linked Lists | Stacks can also be implemented using linked lists. |
| Loops | Used to display or process stack elements. |
| Conditional Statements | Used to check stack overflow, underflow, empty, or full conditions. |
| Functions / Methods | Stack operations are usually written as methods such as push(), pop(), and peek(). |
| Basic Memory Concept | Helps understand how stack elements are stored and removed. |
Real-World Analogy of Stack
A common real-world example of a stack is a pile of plates. When plates are stacked on top of each other, the last plate placed on the stack is the first plate removed.
You cannot easily remove the bottom plate without first removing the plates above it. This is exactly how a stack works in programming.
Stack as a Pile of Plates
The last plate added to the pile is removed first. This is the same as stack behavior: Last In, First Out.
| Real-World Example | Stack Concept | Explanation |
|---|---|---|
| Pile of plates | LIFO | The last plate placed is removed first. |
| Undo operation | Most recent action first | The latest action is undone first. |
| Browser back button | Recent page first | The last visited page is accessed first when going back. |
| Function calls | Call stack | The latest function call finishes first. |
LIFO Principle
The most important rule of a stack is LIFO. LIFO stands for Last In, First Out. This means the last element inserted into the stack will be the first element removed from the stack.
Suppose we insert elements in this order:
Push 10
Push 20
Push 30
The stack will look like this:
Top -> 30
20
10
If we remove an element, 30 will be removed first because it was inserted last.
Stack Top
The top is the position where insertion and deletion happen in a stack. The top always points to the most recently added element.
If the stack is empty, there is no top element. When a new element is pushed, it becomes the top. When the top element is popped, the element below it becomes the new top.
Basic Stack Operations
A stack supports several basic operations. These operations are used to add, remove, view, and check stack elements.
| Operation | Meaning | Example |
|---|---|---|
| push() | Adds an element to the top of the stack. | push(10) |
| pop() | Removes the top element from the stack. | pop() |
| peek() / top() | Returns the top element without removing it. | peek() |
| isEmpty() | Checks whether the stack is empty. | isEmpty() |
| isFull() | Checks whether the stack is full in fixed-size stack. | isFull() |
| display() | Displays stack elements. | display() |
Push Operation
The push operation adds a new element to the top of the stack. After pushing, the newly added element becomes the top element.
// Conceptual push operation
push(10)
push(20)
push(30)
Stack after these operations:
Top -> 30
20
10
Pop Operation
The pop operation removes the top element from the stack. After popping, the next element below it becomes the new top.
// Before pop
Top -> 30
20
10
pop()
// After pop
Top -> 20
10
In this example, 30 is removed because it was the top element.
Peek Operation
The peek operation returns the top element of the stack without removing it. It is useful when we want to check the latest element but keep it in the stack.
// Stack
Top -> 30
20
10
peek() returns 30
After peek(), the stack remains unchanged.
isEmpty Operation
The isEmpty operation checks whether the stack has no elements. This is important before performing pop or peek operations.
// Conceptual isEmpty
if stack is empty:
print "Stack is empty"
else:
print "Stack has elements"
Stack Overflow and Underflow
In stack operations, two common error conditions are overflow and underflow.
| Condition | Meaning | When It Happens |
|---|---|---|
| Stack Overflow | Trying to push into a full stack. | Fixed-size stack has no more space. |
| Stack Underflow | Trying to pop from an empty stack. | No element exists to remove. |
Stack Overflow
- Occurs during push operation.
- Happens when stack is already full.
- Common in fixed-size stack implementation.
Stack Underflow
- Occurs during pop or peek operation.
- Happens when stack is empty.
- Can be avoided by checking isEmpty().
Stack Conceptual Implementation
A stack can be implemented using an array, list, or linked list. The following conceptual example shows basic stack logic.
// Conceptual stack operations
stack = empty list
push(value):
add value to top of stack
pop():
if stack is empty:
print "Stack underflow"
else:
remove top value
peek():
if stack is empty:
print "Stack is empty"
else:
return top value
Java Example: Stack Using Array
The following Java example shows a simple stack implementation using an array.
class Stack {
int[] stack;
int top;
int size;
Stack(int stackSize) {
size = stackSize;
stack = new int[size];
top = -1;
}
void push(int value) {
if (top == size - 1) {
System.out.println("Stack overflow");
} else {
top++;
stack[top] = value;
System.out.println(value + " pushed into stack");
}
}
void pop() {
if (top == -1) {
System.out.println("Stack underflow");
} else {
System.out.println(stack[top] + " popped from stack");
top--;
}
}
void peek() {
if (top == -1) {
System.out.println("Stack is empty");
} else {
System.out.println("Top element: " + stack[top]);
}
}
void display() {
if (top == -1) {
System.out.println("Stack is empty");
} else {
System.out.println("Stack elements:");
for (int i = top; i >= 0; i--) {
System.out.println(stack[i]);
}
}
}
}
public class Main {
public static void main(String[] args) {
Stack stack = new Stack(5);
stack.push(10);
stack.push(20);
stack.push(30);
stack.peek();
stack.display();
stack.pop();
stack.display();
}
}
In this example, the variable top keeps track of the current top element. When push is performed, top increases. When pop is performed, top decreases.
JavaScript Example: Stack Using Array
JavaScript arrays provide built-in methods that make stack operations easy. The push() method adds an element to the end, and the pop() method removes the last element.
class Stack {
constructor() {
this.items = [];
}
push(value) {
this.items.push(value);
console.log(value + " pushed into stack");
}
pop() {
if (this.isEmpty()) {
console.log("Stack underflow");
} else {
const removedValue = this.items.pop();
console.log(removedValue + " popped from stack");
}
}
peek() {
if (this.isEmpty()) {
console.log("Stack is empty");
} else {
console.log("Top element: " + this.items[this.items.length - 1]);
}
}
isEmpty() {
return this.items.length === 0;
}
display() {
if (this.isEmpty()) {
console.log("Stack is empty");
} else {
console.log("Stack elements:");
for (let i = this.items.length - 1; i >= 0; i--) {
console.log(this.items[i]);
}
}
}
}
const stack = new Stack();
stack.push(10);
stack.push(20);
stack.push(30);
stack.peek();
stack.display();
stack.pop();
stack.display();
This JavaScript example shows how a stack can be created using an array internally.
Stack Using Linked List
A stack can also be implemented using a linked list. In linked-list-based stack implementation, the top of the stack is usually represented by the head node.
When pushing a new element, a new node is added at the beginning. When popping, the first node is removed.
Linked-list-based stacks can grow dynamically because nodes are created as needed.
Stack Using Array vs Linked List
| Basis | Array-Based Stack | Linked-List-Based Stack |
|---|---|---|
| Size | May be fixed. | Can grow dynamically. |
| Memory | Uses continuous memory in many languages. | Uses nodes stored separately. |
| Overflow | Can occur if fixed-size array becomes full. | Less likely unless memory is unavailable. |
| Implementation | Usually simpler for beginners. | Requires node and link management. |
| Best Use | When maximum size is known. | When size changes frequently. |
Real-World Example: Undo Feature
One of the best real-world examples of a stack is the undo feature in text editors or design tools. Every action performed by the user is pushed into a stack. When the user clicks undo, the latest action is popped from the stack and reversed.
Action Stack:
Top -> Delete Text
Change Color
Insert Image
Type Text
If the user presses undo, Delete Text is undone first because it is at the top of the stack.
Real-World Example: Browser History
Browser history can also use stack-like behavior. When a user visits pages, each page can be pushed onto a stack. When the user presses the back button, the most recent page is popped first.
Visited Pages:
Top -> Contact Page
Products Page
Home Page
Pressing back removes Contact Page and returns to Products Page.
Real-World Example: Function Call Stack
Programming languages use a stack internally to manage function calls. When a function is called, it is added to the call stack. When the function finishes, it is removed from the stack.
main() calls functionA()
functionA() calls functionB()
Call Stack:
Top -> functionB()
functionA()
main()
functionB() finishes first, then functionA(), and finally main().
Stack in Expression Checking
Stacks are commonly used to check whether brackets are balanced in expressions.
Example of balanced expression:
( A + B ) * ( C + D )
Example of unbalanced expression:
( A + B * ( C + D )
A stack can store opening brackets and remove them when matching closing brackets are found.
Stack in Backtracking
Backtracking is a problem-solving technique where a program tries one path, and if it fails, it goes back and tries another path. Stack is useful here because the most recent decision is reversed first.
Backtracking is used in:
- Maze solving
- Sudoku solving
- Path finding
- Recursion-based problems
- Depth-first search
Common Applications of Stack
| Application | How Stack is Used |
|---|---|
| Undo / Redo | Stores recent actions and reverses the latest action first. |
| Browser History | Tracks visited pages and moves back to the latest previous page. |
| Function Calls | Manages function execution using call stack. |
| Recursion | Each recursive call is stored in the call stack. |
| Expression Evaluation | Helps evaluate postfix, prefix, and infix expressions. |
| Bracket Matching | Checks whether parentheses and brackets are balanced. |
| Backtracking | Stores choices and reverses latest choices when needed. |
| Depth-First Search | Graph and tree traversal can use stack behavior. |
Advantages of Stack
Stacks are simple but powerful. They are very useful when data must be processed in reverse order.
Benefits of Stack
- Simple and easy to understand.
- Follows a clear LIFO rule.
- Useful for reverse-order processing.
- Helps implement undo and redo features.
- Supports function call management.
- Useful in recursion.
- Helpful in expression evaluation.
- Useful for backtracking algorithms.
- Can be implemented using arrays or linked lists.
- Efficient push and pop operations at the top.
Limitations of Stack
Although stacks are useful, they are not suitable for every problem. Stack access is limited to the top element only.
Stack vs Array
A stack can be implemented using an array, but a stack and an array are conceptually different. An array allows access using index, while a stack restricts access to the top element only.
| Basis | Array | Stack |
|---|---|---|
| Access | Elements can be accessed by index. | Only top element is directly accessible. |
| Order Rule | No strict removal order. | Follows LIFO rule. |
| Insertion | Can happen at different positions. | Happens at top. |
| Deletion | Can happen from different positions. | Happens from top. |
| Best Use | General list storage and index access. | Reverse-order processing and undo-like behavior. |
Stack vs Queue
Stack and queue are both linear data structures, but they follow different rules. Stack follows LIFO, while queue follows FIFO.
| Basis | Stack | Queue |
|---|---|---|
| Rule | Last In, First Out | First In, First Out |
| Insertion | At top | At rear |
| Deletion | From top | From front |
| Real-World Example | Stack of plates | Line at ticket counter |
| Use Case | Undo, recursion, backtracking | Scheduling, waiting lines, task processing |
When Should You Use Stack?
Stack should be used when the latest item must be processed first. If the problem requires reverse-order processing, stack is often a good choice.
Use Stack When
- You need Last In, First Out behavior.
- You need to undo recent actions.
- You need to manage function calls.
- You need to solve recursion-based problems.
- You need to check balanced brackets.
- You need to evaluate expressions.
- You need backtracking.
- You need depth-first traversal.
Common Mistakes Beginners Make
Beginners often confuse stack with array or queue. Understanding stack rules clearly helps avoid mistakes.
Common Mistakes
- Confusing stack with queue.
- Forgetting that stack follows LIFO.
- Trying to remove elements from the bottom.
- Trying to access any element directly like an array.
- Not checking if stack is empty before pop.
- Not checking if fixed-size stack is full before push.
- Confusing peek with pop.
- Not updating top correctly in manual implementation.
Better Approach
- Remember LIFO: Last In, First Out.
- Push adds to top.
- Pop removes from top.
- Peek only reads the top element.
- Check isEmpty() before pop or peek.
- Check isFull() for fixed-size stack.
- Use diagrams to trace stack operations.
- Practice with real examples like undo and browser history.
Best Practices for Learning Stack
Stack becomes easy when students understand the LIFO rule and practice push, pop, and peek operations visually.
Recommended Practices
- Start with real-world examples like plates and undo feature.
- Draw stack diagrams before writing code.
- Understand top clearly.
- Practice push operation step by step.
- Practice pop operation step by step.
- Understand the difference between pop and peek.
- Check empty stack condition before removing values.
- Implement stack using array first.
- Then understand stack using linked list.
- Practice applications like balanced parentheses and undo operation.
Mini Practice Activity
Complete the following practice tasks to strengthen your understanding of stacks.
| Task | Description | Expected Learning |
|---|---|---|
| Task 1 | Draw a stack after pushing 10, 20, and 30. | Understand push operation and top position. |
| Task 2 | Perform one pop operation and draw the stack again. | Understand pop operation. |
| Task 3 | Write the result of peek() after pushing 5, 15, and 25. | Understand top element access. |
| Task 4 | Explain stack overflow with an example. | Understand fixed-size stack limitation. |
| Task 5 | Explain stack underflow with an example. | Understand empty stack condition. |
| Task 6 | Give three real-world examples of stack behavior. | Connect stack with real life. |
Frequently Asked Questions
1. What is a stack?
A stack is a linear data structure that follows the Last In, First Out principle. The last element added is the first element removed.
2. What does LIFO mean?
LIFO means Last In, First Out. It means the most recently inserted element is removed first.
3. What is push operation?
Push is the operation of adding a new element to the top of the stack.
4. What is pop operation?
Pop is the operation of removing the top element from the stack.
5. What is peek operation?
Peek returns the top element of the stack without removing it.
6. What is stack overflow?
Stack overflow occurs when we try to push an element into a full fixed-size stack.
7. What is stack underflow?
Stack underflow occurs when we try to pop or peek from an empty stack.
8. Can stack be implemented using array?
Yes. A stack can be implemented using an array by tracking the top position.
9. Can stack be implemented using linked list?
Yes. A stack can be implemented using a linked list by adding and removing nodes from the head.
10. Where is stack used in real life?
Stack is used in undo features, browser history, function calls, recursion, expression evaluation, balanced bracket checking, and backtracking.
Summary
A stack is a linear data structure that follows the LIFO principle, which means Last In, First Out. Elements are inserted and removed from the same end called the top.
The main stack operations are push, pop, peek, isEmpty, and display. Push adds an element to the top, pop removes the top element, and peek returns the top element without removing it.
Stacks are used in many important areas of programming, including undo operations, browser history, function calls, recursion, expression evaluation, balanced bracket checking, and backtracking algorithms.
Key Takeaway
A stack is a linear data structure that follows the LIFO rule: Last In, First Out. It is useful when the most recent item must be processed first, such as in undo operations, browser history, function calls, recursion, and backtracking.