Understanding the Stack — From Concept to Code
Understanding the Stack — From Concept to Code
The stack is one of the most fundamental and powerful data structures in computer science. It is used in everything from expression evaluation and recursive function calls to undo features in editors and backtracking algorithms. In this post, we'll understand what a stack really is, how it functions as an Abstract Data Type (ADT), and how to implement one in C.
What Is a Stack?
A stack is a linear data structure that follows the LIFO principle — Last In, First Out. That means the last element inserted is the first one to be removed. Think of it like a stack of plates: you can only add or remove from the top.
Basic Operations of a Stack:
push()
– Add an element to the toppop()
– Remove the top elementpeek()/top()
– View the top elementisEmpty()
– Check if the stack is emptyisFull()
– (For fixed-size stacks)
Stack as an Abstract Data Type (ADT)
As an ADT, a stack defines its behavior (how it should work) without dictating the internal implementation (how it is built). It simply specifies:
- You can push and pop
- You cannot access the middle elements directly
- The operations should follow LIFO rules
Whether you implement it using an array, linked list, or even a dynamic structure, the interface remains the same. That’s the beauty of an ADT — it provides abstraction.
Stack Implementation in C (Array Version)
#include <stdio.h>
#define MAX 100
int stack[MAX];
int top = -1;
// Push operation
void push(int value) {
if (top == MAX - 1)
printf("Stack Overflow\n");
else
stack[++top] = value;
}
// Pop operation
int pop() {
if (top == -1) {
printf("Stack Underflow\n");
return -1;
} else {
return stack[top--];
}
}
// Peek operation
int peek() {
if (top == -1) {
printf("Stack is Empty\n");
return -1;
} else {
return stack[top];
}
}
// Display stack
void display() {
if (top == -1)
printf("Stack is Empty\n");
else {
printf("Stack elements: ");
for (int i = top; i >= 0; i--)
printf("%d ", stack[i]);
printf("\n");
}
}
int main() {
push(10);
push(20);
push(30);
display();
printf("Popped element: %d\n", pop());
printf("Top element: %d\n", peek());
display();
return 0;
}
Sample Output:
Stack elements: 30 20 10
Popped element: 30
Top element: 20
Stack elements: 20 10
Where Stacks Are Used
- Expression evaluation (Infix to Postfix, Postfix evaluation)
- Function call management (Call stack)
- Backtracking problems (Maze, recursion)
- Undo/Redo systems
- Browser history navigation
Stack Implementation in Python (Class-Based)
In higher-level languages like Python, implementing a stack becomes more abstracted and intuitive. Here’s a class-based dynamic implementation using Python’s built-in list data structure:
class Stack:
def __init__(self):
self.stack = []
def push(self, value):
self.stack.append(value)
def pop(self):
if not self.is_empty():
return self.stack.pop()
else:
print("Stack Underflow")
return None
def peek(self):
if not self.is_empty():
return self.stack[-1]
else:
print("Stack is Empty")
return None
def is_empty(self):
return len(self.stack) == 0
def display(self):
print("Stack (top to bottom):", self.stack[::-1])
# Example usage:
s = Stack()
s.push(10)
s.push(20)
s.push(30)
s.display()
print("Popped:", s.pop())
print("Top:", s.peek())
s.display()
Sample Output:
Stack (top to bottom): [30, 20, 10]
Popped: 30
Top: 20
Stack (top to bottom): [20, 10]
Such implementations are ideal for scripting, web development, algorithm tutorials, and teaching data structures in a beginner-friendly way.
Conclusion
Stacks are deceptively simple, but their use cases are everywhere in computer science. As an ADT, they represent the idea of a tightly controlled access structure — you don’t need to know what’s inside, only how to interact with it. Learn stacks well, and you’ll unlock the building blocks of compilers, memory models, and algorithm design.
Comments
Post a Comment