📚 Stack
Learn the LIFO principle, understand push/pop/peek operations, visualize an array-based stack, and trace the exact C program step by step.
📖 Stack Overview
A stack is a linear data structure in which insertion and deletion happen at only one end, called the top.
💡 LIFO Principle
Stack follows Last In, First Out (LIFO). The most recently inserted element is the first element removed.
🧠 Simple Example
Push 10, then 20, then 30.
The stack becomes 10, 20, 30 from bottom to top.
A Pop operation removes 30 first.
Real-life examples
- A pile of plates.
- Undo operations in an editor.
- Function-call management using the runtime call stack.
- Expression conversion and evaluation.
- Backtracking algorithms.
⚙️ Basic Stack Operations
Array Stack Rule
For an array implementation, top = -1 means the stack is empty.
After a successful push, top increases by one.
After a successful pop, top decreases by one.
🧱 Stack Using Array
An array can store the stack elements, while an integer variable named top
records the index of the current top element.
#define MAX 5
int stack[MAX];
int top = -1;
Example
If the array contains 10, 20, 30, then top = 2.
The top element is stack[2] = 30.
⬆️ Push Operation
Push inserts a new value at the top of the stack. Before insertion, an array stack must check for overflow.
Algorithm
PUSH(value)
1. If top == MAX - 1
report Stack Overflow
stop
2. top = top + 1
3. stack[top] = value
top first, then store the new value in
stack[top].
⬇️ Pop Operation
Pop removes the current top element. Before removal, the stack must check for underflow.
Algorithm
POP()
1. If top == -1
report Stack Underflow
stop
2. value = stack[top]
3. top = top - 1
4. return value
top.
The old array value may still exist in memory, but it is no longer part of the stack.
👀 Peek Operation
Peek returns the top value without changing the stack.
Algorithm
PEEK()
1. If top == -1
report Stack Empty
stop
2. return stack[top]
Example
For stack 10, 20, 30 with top = 2,
Peek returns 30 and top remains 2.
💻 Array Stack Program in C
Visible Learning Program
#include <stdio.h>
#define MAX 5
int stack[MAX];
int top = -1;
void push(int value)
{
if(top == MAX - 1)
{
printf("Overflow\n");
return;
}
top++;
stack[top] = value;
}
int pop()
{
int value;
if(top == -1)
return -1;
value = stack[top];
top--;
return value;
}
int peek()
{
if(top == -1)
return -1;
return stack[top];
}
int main()
{
push(10);
push(20);
push(30);
printf("Popped: %d\n", pop());
printf("Top: %d\n", peek());
return 0;
}
Output
Popped: 30
Top: 20
Final Stack
20 ← TOP
10
💻 Program
🧠 What is happening?
📊 Live Variables
📦 Live Stack Array
⚡ Time and Space Complexity
stack[top].
🔗 Stack Using Linked List
A stack can also be implemented using a singly linked list. In this implementation, the head node acts as TOP.
💡 Core Idea
Push inserts a new node at the beginning of the linked list. Pop deletes the first node. Because both operations work at the head, they take O(1) time.
Node Structure
struct Node
{
int data;
struct Node *next;
};
struct Node *top = NULL;
top always stores the address of the most recently pushed node.
top integer index. Here, top is a
pointer to the first node.
⚙️ Linked Stack Operations
Push Algorithm
PUSH(value)
1. Create newNode
2. newNode->data = value
3. newNode->next = top
4. top = newNode
Pop Algorithm
POP()
1. If top == NULL
report Underflow
stop
2. temp = top
3. value = temp->data
4. top = top->next
5. free(temp)
6. return value
Peek Algorithm
PEEK()
1. If top == NULL
report Empty Stack
stop
2. return top->data
💻 Linked List Stack Program in C
Visible Learning Program
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *top = NULL;
void push(int value)
{
struct Node *newNode =
(struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = top;
top = newNode;
}
int pop()
{
struct Node *temp;
int value;
if(top == NULL)
return -1;
temp = top;
value = temp->data;
top = top->next;
free(temp);
return value;
}
int peek()
{
if(top == NULL)
return -1;
return top->data;
}
int main()
{
push(10);
push(20);
push(30);
printf("Popped: %d\n", pop());
printf("Top: %d\n", peek());
return 0;
}
Output
Popped: 30
Top: 20
Final Linked Stack
TOP → 20 → 10 → NULL
💻 Program
🧠 What is happening?
📊 Live Variables
🔗 Live Linked Stack Memory
⚡ Linked List Stack Complexity
top->data directly.
| Feature | Array Stack | Linked List Stack |
|---|---|---|
| TOP representation | Integer index | Node pointer |
| Capacity | Usually fixed | Dynamic while memory is available |
| Push / Pop / Peek | O(1) | O(1) |
| Extra memory per element | No link pointer | One next pointer |
| Main failure case | Array overflow | Memory allocation failure |
🧩 Parentheses Balancing Using Stack
A stack is commonly used to verify whether brackets in an expression are properly balanced.
The important bracket pairs are (), {}, and [].
💡 Core Idea
Push every opening bracket onto the stack. For a closing bracket, the stack must not be empty, and its TOP must contain the matching opening bracket. After the full expression is processed, the stack must be empty.
(, {, or [, push it onto the stack.
), }, or ], compare it with the current TOP.
🧠 Example
For {[()]}: push {, push [, push (,
then each closing bracket matches and removes its corresponding opening bracket.
The final stack is empty, so the expression is balanced.
Algorithm
IS_BALANCED(expression)
1. Create an empty stack
2. For each character ch in expression:
If ch is an opening bracket
Push ch
Else if ch is a closing bracket
If stack is empty
return Not Balanced
Pop top bracket
If popped bracket does not match ch
return Not Balanced
3. If stack is empty
return Balanced
Else
return Not Balanced
💻 Parentheses Balancing Program in C
Visible Learning Program
#include <stdio.h>
#include <string.h>
int isMatching(char open, char close)
{
return (open == '(' && close == ')') ||
(open == '{' && close == '}') ||
(open == '[' && close == ']');
}
int main()
{
char expr[100];
char stack[100];
int top = -1;
int balanced = 1;
scanf("%99s", expr);
for(int i = 0; expr[i] != '\0'; i++)
{
char ch = expr[i];
if(ch == '(' || ch == '{' || ch == '[')
{
top++;
stack[top] = ch;
}
else if(ch == ')' || ch == '}' || ch == ']')
{
if(top == -1)
{
balanced = 0;
break;
}
if(!isMatching(stack[top], ch))
{
balanced = 0;
break;
}
top--;
}
}
if(top != -1)
balanced = 0;
if(balanced)
printf("Balanced\n");
else
printf("Not Balanced\n");
return 0;
}
Sample Input
{[()]}
Sample Output
Balanced
💻 Program
🧠 What is happening?
📊 Live Variables
🧩 Live Expression + Stack
⚡ Parentheses Balancing Complexity
(] has the correct count of opening/closing brackets but is still invalid
because the bracket types do not match.
🔁 Infix to Postfix Conversion
In an infix expression, operators appear between operands, such as
A+B*C. In a postfix expression, operators appear after their operands,
such as ABC*+.
💡 Why use a Stack?
Operands can be copied directly to the postfix output, but operators must wait until their precedence and parentheses rules are resolved. A stack temporarily stores those operators.
( is found, then discard the pair.
Operator Precedence
| Operator | Meaning | Precedence | Associativity |
|---|---|---|---|
^ | Exponent | 3 | Right to Left |
* / % | Multiply / Divide / Mod | 2 | Left to Right |
+ - | Add / Subtract | 1 | Left to Right |
🧠 Example
For A+B*(C-D), the postfix form is ABCD-*+.
The parentheses control when - is emitted, and multiplication is emitted before addition.
Algorithm
INFIX_TO_POSTFIX(expression)
1. Create an empty operator stack
2. Scan expression from left to right
3. If token is an operand
append token to postfix
4. Else if token is '('
push it
5. Else if token is ')'
pop and append until '(' is found
pop '(' and discard it
6. Else token is an operator
while stack TOP contains an operator with
higher precedence, or equal precedence
for a left-associative operator:
pop TOP and append it
push current operator
7. After scanning the expression,
pop all remaining operators to postfix
💻 Infix to Postfix Program in C
Visible Learning Program
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int precedence(char op)
{
if(op == '^')
return 3;
if(op == '*' || op == '/' || op == '%')
return 2;
if(op == '+' || op == '-')
return 1;
return 0;
}
int isRightAssociative(char op)
{
return op == '^';
}
int main()
{
char infix[100];
char stack[100];
char postfix[100];
int top = -1;
int k = 0;
scanf("%99s", infix);
for(int i = 0; infix[i] != '\0'; i++)
{
char ch = infix[i];
if(isalnum((unsigned char)ch))
{
postfix[k++] = ch;
}
else if(ch == '(')
{
stack[++top] = ch;
}
else if(ch == ')')
{
while(top != -1 && stack[top] != '(')
postfix[k++] = stack[top--];
if(top != -1)
top--;
}
else
{
while(top != -1 &&
stack[top] != '(' &&
(precedence(stack[top]) > precedence(ch) ||
(precedence(stack[top]) == precedence(ch) &&
!isRightAssociative(ch))))
{
postfix[k++] = stack[top--];
}
stack[++top] = ch;
}
}
while(top != -1)
postfix[k++] = stack[top--];
postfix[k] = '\0';
printf("%s\n", postfix);
return 0;
}
Sample Input
A+B*(C-D)
Sample Output
ABCD-*+
💻 Program
🧠 What is happening?
📊 Live Variables
🔁 Live Expression + Operator Stack + Postfix
⚡ Infix to Postfix Complexity
+, -,
*, and / cause the existing TOP operator to be popped first.
The exponent operator ^ is usually treated as right-associative, so equal-precedence
^ is not popped before pushing the new one.
🧮 Postfix Expression Evaluation
A postfix expression places each operator after its operands.
For example, 23* means 2 * 3.
A stack evaluates postfix expressions naturally in one left-to-right scan.
💡 Core Idea
Push every operand onto the stack. When an operator is found, pop the
second operand first as b, then pop the
first operand as a, compute a operator b,
and push the result back.
b, pop a, compute a op b.
🧠 Example
For 23*54*+9-:
2*3 = 6, 5*4 = 20,
6+20 = 26, and 26-9 = 17.
The final answer is 17.
Algorithm
EVALUATE_POSTFIX(expression)
1. Create an empty value stack
2. Scan postfix expression from left to right
3. If token is an operand
push its numeric value
4. Else token is an operator
b = pop()
a = pop()
result = a operator b
push(result)
5. After scanning all tokens
answer = pop()
6. The stack should now be empty
... a, b, then evaluate
a - b or a / b,
not the reverse.
💻 Postfix Evaluation Program in C
Visible Learning Program
#include <stdio.h>
#include <ctype.h>
int main()
{
char postfix[100];
int stack[100];
int top = -1;
scanf("%99s", postfix);
for(int i = 0; postfix[i] != '\0'; i++)
{
char ch = postfix[i];
if(isdigit((unsigned char)ch))
{
stack[++top] = ch - '0';
}
else
{
int b = stack[top--];
int a = stack[top--];
int result = 0;
switch(ch)
{
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
stack[++top] = result;
}
}
printf("%d\n", stack[top]);
return 0;
}
Sample Input
23*54*+9-
Sample Output
17
💻 Program
🧠 What is happening?
📊 Live Variables
🧮 Live Postfix Expression + Value Stack
⚡ Postfix Evaluation Complexity
82-, the stack pops b = 2 and then a = 8,
so the result is 8 - 2 = 6.
❓ Common Stack Interview Questions
Review the most important Stack ADT, implementation, balancing, conversion, and evaluation questions.
top == MAX - 1. Underflow occurs when Pop or Peek is attempted while
top == -1.
(] contains one opening and one closing bracket but is invalid.
A^B^C, the intended grouping is
A^(B^C). Therefore an existing ^ of equal precedence should not be popped
before pushing the new ^.
b, the second pop gives a,
and the expression must be evaluated as a op b.
🎯 20 Stack Practice Problems
Try every problem yourself first. Use 💻 Solve It Yourself to write and test your C program. Open Hint only when necessary, and use Show Program when you want to study the complete solution.
🏆 Scoring
Pass all 5 tests without help for up to 100 points. Opening a hint caps the competitive score at 90. Opening the official program still lets you complete the problem, but it is recorded as Completed rather than competitively solved.