Implementing Stack Data Structure
Stacks are a Last-In, First-Out (LIFO) data structure that supports four main operations: Push, Pop, Peek (Top), and IsEmpty. In this lesson, we will first explain these operations in detail and then implement a stack using arrays and linked lists.
1. Stack Operations
1.1 Push Operation (Adding an Element to the Stack)
The Push operation adds an element to the top of the stack. If the stack is full (for a fixed-size array implementation), it results in a stack overflow error.
Steps for Push Operation:
- Check if the stack is full.
- If not full, increment the top index.
- Insert the new element at the top index.
- The new element becomes the topmost element in the stack.
Example Push:
- Time Complexity:
→ Directly inserting at the end. - Space Complexity:
→ No extra space required.
1.2 Pop Operation (Removing the Top Element)
The Pop operation removes the topmost element from the stack. If the stack is empty, it results in a stack underflow error.
Steps for Pop Operation:
- Check if the stack is empty.
- Retrieve the top element.
- Remove the top element by decrementing the top index.
- Return the removed element.
Example Pop:
- Time Complexity:
→ Directly removing the last element. - Space Complexity:
→ No extra space required.
1.3 Peek (Top) Operation (Viewing the Top Element Without Removing It)
The Peek operation allows us to look at the top element without modifying the stack.
Steps for Peek Operation:
- Check if the stack is empty.
- Return the topmost element without removing it.
Example Peek:
Stack: [10, 20, 30, 40] (Top = 40) Peek() → Returns 40 Stack remains unchanged.
- Time Complexity:
→ Direct index access. - Space Complexity:
→ No extra space required.
1.4 IsEmpty Operation (Checking If the Stack is Empty)
The IsEmpty operation checks whether the stack contains any elements.
Steps for IsEmpty Operation:
- If the stack has no elements, return
true. - Otherwise, return
false.
Example IsEmpty Operation:
Stack: [10, 20, 30] IsEmpty() → Returns False Stack: [] IsEmpty() → Returns True
- Time Complexity:
- Space Complexity:
2. Implementing Stack Using an Array in Java
An array-based stack provides
Code
// Stack implementation using an array
class Solution {
private int[] stack;
private int top;
private int capacity;
// Constructor to initialize stack
public Solution(int capacity) {
this.capacity = capacity;
stack = new int[capacity];
top = -1; // Stack is initially empty
}
// Push operation
public void push(int value) {
if (top == capacity - 1) {
System.out.println("Stack Overflow! Cannot push " + value);
return;
}
stack[++top] = value;
System.out.println(value + " pushed to stack.");
}
// Pop operation
public int pop() {
if (isEmpty()) {
System.out.println("Stack Underflow! No elements to pop.");
return -1; // Return -1 to indicate error
}
return stack[top--];
}
// Peek operation
public int peek() {
if (isEmpty()) {
System.out.println("Stack is empty!");
return -1;
}
return stack[top];
}
// Check if the stack is empty
public boolean isEmpty() {
return top == -1;
}
// Main method to demonstrate stack operations
public static void main(String[] args) {
Solution stack = new Solution(5);
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println("Top element: " + stack.peek()); // Output: 30
System.out.println("Popped: " + stack.pop()); // Output: 30
System.out.println("Popped: " + stack.pop()); // Output: 20
System.out.println("Is stack empty? " + stack.isEmpty()); // Output: false
stack.pop(); // Popping last element
System.out.println("Is stack empty? " + stack.isEmpty()); // Output: true
}
}
3. Implementing Stack Using a Linked List in Java
A linked list-based stack overcomes the fixed-size limitation of an array, allowing for dynamic memory allocation.
Code
// Stack implementation using a linked list
// class ListNode {
// int val;
// ListNode next;
// ListNode(int x) { val = x; }
// }
class Solution {
private ListNode top; // Top of the stack
// Constructor
public Solution() {
this.top = null;
}
// Push operation
public void push(int value) {
ListNode newNode = new ListNode(value);
newNode.next = top;
top = newNode;
System.out.println(value + " pushed to stack.");
}
// Pop operation
public int pop() {
if (isEmpty()) {
System.out.println("Stack Underflow! No elements to pop.");
return -1;
}
int poppedValue = top.val;
top = top.next;
return poppedValue;
}
// Peek operation
public int peek() {
if (isEmpty()) {
System.out.println("Stack is empty!");
return -1;
}
return top.val;
}
// Check if the stack is empty
public boolean isEmpty() {
return top == null;
}
// Main method to demonstrate stack operations
public static void main(String[] args) {
Solution stack = new Solution();
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println("Top element: " + stack.peek()); // Output: 30
System.out.println("Popped: " + stack.pop()); // Output: 30
System.out.println("Popped: " + stack.pop()); // Output: 20
System.out.println("Is stack empty? " + stack.isEmpty()); // Output: false
stack.pop(); // Popping last element
System.out.println("Is stack empty? " + stack.isEmpty()); // Output: true
}
}
4. Key Takeaways
- Array-based stacks are simple but have a fixed size.
- Linked list-based stacks provide dynamic memory but require extra space for pointers.
- Both implementations offer O(1) time complexity for all operations.
Understanding stack operations and implementations is crucial for solving coding problems efficiently!
🤖 Don't fully get this? Learn it with Claude
Stuck on Implementing Stack Data Structure? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Implementing Stack Data Structure** (DSA) and want to truly understand it. Explain Implementing Stack Data Structure from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Implementing Stack Data Structure** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Implementing Stack Data Structure** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Implementing Stack Data Structure** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.