Stack
A stack is a linear data structure that follows a specific order for operations.
Characteristics
- LIFO (Last In First Out): The last element added is the first one removed
- FILO (First In Last Out): The first element added is the last one removed
- Both terms describe the same behavior from different perspectives
Visual Representation:
Top
↓
┌───┐
│ 5 │ ← Last pushed (will be first popped)
├───┤
│ 3 │
├───┤
│ 7 │
├───┤
│ 2 │ ← First pushed (will be last popped)
└───┘
Stack Operations
Basic Operations
- Push: Add an element to the top of the stack
- Pop: Remove and return the top element
- Peek (or Top): View the top element without removing it
- isEmpty: Check if the stack is empty
- isFull: Check if the stack is full (for fixed-size arrays)
Implementation (Array-Based)
Stack Structure
#define MAX_SIZE 100
struct Stack {
int arr[MAX_SIZE];
int top; // Index of top element
};Convention:
top = -1indicates an empty stacktop = MAX_SIZE - 1indicates a full stack
1. Initialize Stack
void initStack(struct Stack *S) {
S->top = -1; // Stack is initially empty
}2. Check if Stack is Empty
bool isEmpty(struct Stack *S) {
return (S->top == -1);
}Time Complexity:
3. Check if Stack is Full
bool isFull(struct Stack *S) {
return (S->top == MAX_SIZE - 1);
}Time Complexity:
4. Push Operation
Algorithm:
Push(S, x):
if top >= MAX_SIZE - 1:
print "Stack Overflow"
return
else:
top = top + 1
S[top] = xImplementation in C:
void push(struct Stack *S, int x) {
if (isFull(S)) {
printf("Stack Overflow: Cannot push %d\n", x);
return;
}
S->top = S->top + 1;
S->arr[S->top] = x;
}Time Complexity:
Example:
Before: top = 2 After: top = 3
┌───┐ ┌───┐
│ 5 │ ← top │ 9 │ ← top (new element)
├───┤ ├───┤
│ 3 │ │ 5 │
├───┤ ├───┤
│ 7 │ │ 3 │
└───┘ ├───┤
│ 7 │
└───┘
Push(S, 9)
5. Pop Operation
Algorithm:
Pop(S):
if top == -1:
print "Stack Underflow"
return NULL
else:
x = S[top]
top = top - 1
return xImplementation in C:
int pop(struct Stack *S) {
if (isEmpty(S)) {
printf("Stack Underflow: Cannot pop from empty stack\n");
return -1; // Error value
}
int x = S->arr[S->top];
S->top = S->top - 1;
return x;
}Time Complexity:
Example:
Before: top = 3 After: top = 2
┌───┐ ┌───┐
│ 9 │ ← top (removed) │ 5 │ ← top
├───┤ ├───┤
│ 5 │ │ 3 │
├───┤ ├───┤
│ 3 │ │ 7 │
├───┤ └───┘
│ 7 │
└───┘
x = Pop(S) // x = 9
6. Peek Operation
Algorithm:
Peek(S):
if top == -1:
print "Stack is empty"
return NULL
else:
return S[top]Implementation in C:
int peek(struct Stack *S) {
if (isEmpty(S)) {
printf("Stack is empty\n");
return -1; // Error value
}
return S->arr[S->top];
}Time Complexity:
Applications of Stack
1. Expression Evaluation
Stacks are used to convert and evaluate expressions:
- Infix:
A + B(operator between operands) - Prefix:
+ A B(operator before operands) - Postfix:
A B +(operator after operands)
2. Function Call Management
- Function calls are stored in a call stack
- Local variables and return addresses are pushed/popped
3. Undo/Redo Operations
- Text editors use stacks to track changes
4. Backtracking
- Maze solving, game moves, etc.
5. Parenthesis Matching
- Check balanced brackets:
{[()]}✓ vs{[(])}✗
Complexity Summary
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Push | ||
| Pop | ||
| Peek | ||
| isEmpty | ||
| isFull |
Overall Space:
Key Takeaways
- Stack follows LIFO/FILO principle
- All basic operations are
- Stack Overflow: Trying to push onto a full stack
- Stack Underflow: Trying to pop from an empty stack
- Stacks are fundamental for recursion, expression evaluation, and backtracking