๐ Stack Implementation Using Linked Lists (Push, Pop, Peek, isEmpty & Display)
Welcome to Part 3 of our Stack in Java series.
In Part 1, we learned:
- โ What is a Stack?
- โ LIFO Principle
- โ Stack Terminologies
- โ Applications of Stack
In Part 2, we learned:
- โ Stack Implementation Using Arrays
- โ Push Operation
- โ Pop Operation
- โ Peek Operation
- โ isEmpty()
- โ isFull()
- โ Display Operation
Although an array implementation is simple and efficient, it has one major limitation:
The size of the stack is fixed.
If the array becomes full, no more elements can be inserted.
To overcome this limitation, we use a Linked List.
In this tutorial, you’ll learn how to implement a Stack using a Singly Linked List, where the stack can grow dynamically as memory is available.
๐ Table of Contents
- Why Use a Linked List?
- Stack Representation
- Node Structure
- Top Pointer
- Push Operation
- Pop Operation
- Peek Operation
- isEmpty()
- Display Operation
- Complete Java Program
- Dry Runs
- Time Complexity
- Advantages over Arrays
- Common Mistakes
- FAQs
- Conclusion
๐ค Why Implement Stack Using a Linked List?
Suppose an array-based stack has a capacity of 5.
10
20
30
40
50
Trying to push another element results in:
Stack Overflow
Even if your computer has plenty of free memory, the stack cannot grow because the array size is fixed.
A Linked List solves this problem.
Each new element is stored in a new node, so the stack grows dynamically.
๐ Stack Representation Using a Linked List
Unlike arrays, a linked list does not store elements in contiguous memory.
Each element is stored inside a Node.
Example
Top
โ
+------+-----+
| 40 | โข----|----+
+------+-----+ |
|
+------+-----+
| 30 | โข----|----+
+------+-----+ |
|
+------+-----+
| 20 | โข----|----+
+------+-----+ |
|
+------+-----+
| 10 | NULL |
+------+-----+
Notice that the Top always points to the first node.
๐ง Why is the Top at the Beginning?
Suppose the stack is
Top
โ
40
โ
30
โ
20
โ
10
If the top is stored at the beginning,
both Push and Pop require changing only one reference.
Therefore,
both operations become
O(1)
๐ฆ Node Structure
Every node stores:
- Data
- Reference to the Next Node
Visual Representation
+------+------+
| Data | Next |
+------+------+
๐ป Java Node Class
class Node{
int data;
Node next;
Node(int data){
this.data = data;
next = null;
}
}
๐ Top Pointer
Instead of storing an index,
we store a reference.
Node top;
Initially
top = null
This means
the stack is empty.
โ Push Operation
Push inserts a new node at the beginning.
Suppose
Current Stack
Top
โ
30
โ
20
โ
10
Push
40
Result
Top
โ
40
โ
30
โ
20
โ
10
๐ Algorithm
- Create a new node.
- Point it to the current Top.
- Move Top to the new node.
๐จ Dry Run
Current
Top
โ
30
Create
40
Update
newNode.next = top
Update
top = newNode
Done.
๐ป Java Program โ Push
public void push(int value){
Node newNode = new Node(value);
newNode.next = top;
top = newNode;
}
โ Pop Operation
Pop removes the top node.
Current
Top
โ
40
โ
30
โ
20
Pop
40
Result
Top
โ
30
โ
20
๐ Algorithm
- Check if the stack is empty.
- Store the top value.
- Move Top to the next node.
- Return the deleted value.
๐ป Java Program โ Pop
public int pop(){
if(top == null){
System.out.println("Stack Underflow");
return -1;
}
int value = top.data;
top = top.next;
return value;
}
๐ Peek Operation
Peek returns the top element
without removing it.
Current
Top
โ
40
โ
30
โ
20
Peek
40
Stack remains unchanged.
๐ป Java Program โ Peek
public int peek(){
if(top == null){
System.out.println("Stack is Empty");
return -1;
}
return top.data;
}
โ isEmpty()
Checks whether the stack contains any elements.
๐ป Java Program
public boolean isEmpty(){
return top == null;
}
๐ Display Operation
Display starts from Top.
Current
Top
โ
40
โ
30
โ
20
โ
10
Output
40
30
20
10
๐ป Java Program โ Display
public void display(){
if(top == null){
System.out.println("Stack is Empty");
return;
}
Node temp = top;
while(temp != null){
System.out.println(temp.data);
temp = temp.next;
}
}
๐ป Complete Java Program
class Node{
int data;
Node next;
Node(int data){
this.data = data;
next = null;
}
}
public class Stack{
Node top;
public void push(int value){
Node newNode = new Node(value);
newNode.next = top;
top = newNode;
}
public int pop(){
if(top == null){
System.out.println("Stack Underflow");
return -1;
}
int value = top.data;
top = top.next;
return value;
}
public int peek(){
if(top == null){
System.out.println("Stack is Empty");
return -1;
}
return top.data;
}
public boolean isEmpty(){
return top == null;
}
public void display(){
if(top == null){
System.out.println("Stack is Empty");
return;
}
Node temp = top;
System.out.println("\nStack Elements:");
while(temp != null){
System.out.println(temp.data);
temp = temp.next;
}
}
public static void main(String args[]){
Stack s = new Stack();
s.push(10);
s.push(20);
s.push(30);
s.push(40);
s.display();
System.out.println("\nTop Element = " + s.peek());
System.out.println("\nDeleted = " + s.pop());
s.display();
System.out.println("\nIs Empty? " + s.isEmpty());
}
}
Output
Stack Elements:
40
30
20
10
Top Element = 40
Deleted = 40
Stack Elements:
30
20
10
Is Empty? false
๐ Time Complexity
| Operation | Time Complexity |
|---|---|
| Push | O(1) |
| Pop | O(1) |
| Peek | O(1) |
| isEmpty | O(1) |
| Display | O(n) |
๐พ Space Complexity
Suppose the stack contains n nodes.
Memory required
O(n)
Unlike arrays,
memory is allocated only when a new node is created.
โ๏ธ Array vs Linked List Implementation
| Feature | Array Stack | Linked List Stack |
|---|---|---|
| Memory Size | Fixed | Dynamic |
| Overflow | Possible | Only when memory is exhausted |
| Push | O(1) | O(1) |
| Pop | O(1) | O(1) |
| Memory Usage | May waste unused space | Allocates memory only when needed |
| Implementation | Simple | Slightly more complex |
๐ Advantages of Linked List Stack
โ Dynamic size
โ No fixed capacity
โ No wasted array space
โ Efficient Push and Pop operations
โ Better memory utilization
โ Disadvantages
โ Extra memory is required for storing the next reference.
โ Nodes are not stored contiguously, so cache performance may be lower than arrays.
โ Slightly more complex implementation than an array-based stack.
โ ๏ธ Common Mistakes
โ Forgetting to update top
Wrong
newNode.next = top;
Correct
top = newNode;
โ Forgetting the Underflow Check
Never access
top.data
without first checking
top == null
โ Using the Last Node as Top
For a linked-list implementation, the Top should always be the first node, not the last. Otherwise, Push and Pop operations would require traversal and become O(n) instead of O(1).
โ Frequently Asked Questions
Q1. Why is the Top stored at the beginning?
So that Push and Pop can be performed in O(1) time.
Q2. Can a Linked List Stack overflow?
It can only overflow when the system runs out of available memory.
Q3. Which implementation is better?
- Array: Better when the maximum size is known and memory locality is important.
- Linked List: Better when the stack size is unpredictable.
Q4. Is Push faster in a Linked List?
No. Push is O(1) in both array and linked-list implementations.
Q5. Why doesn’t a Linked List Stack require isFull()?
Because it grows dynamically and does not have a predefined size limit.
๐ฏ Key Takeaways
- ๐ A Linked List provides a dynamic implementation of a Stack.
- ๐ The Top points to the first node.
- โ Push inserts a node at the beginning.
- โ Pop removes the first node.
- ๐ Peek returns the first node’s data.
- ๐ Push, Pop, and Peek all take O(1) time.
- ๐พ Memory is allocated dynamically, avoiding the fixed-size limitation of arrays.
๐ Conclusion
Implementing a Stack using a Linked List eliminates the biggest drawback of an array-based stackโits fixed capacity. Since nodes are created dynamically, the stack can grow as needed, making it ideal for applications where the number of elements is not known in advance.
Although each node requires extra memory for storing the next reference, the flexibility and scalability often outweigh this overhead.
๐ In Part 4, we’ll explore the real-world applications of Stack, including:
- ๐ Function Call Stack
- ๐ Recursion
- ๐งฎ Expression Evaluation
- ๐ Parentheses Matching
- ๐ค Infix to Postfix Conversion
- ๐ก Infix to Prefix Conversion
- ๐ Browser History
- โ๏ธ Undo & Redo
- ๐ณ Depth First Search (DFS)
- ๐ป Java Virtual Machine (JVM) Stack
- ๐ฏ Complete Java examples for important applications