CODEBHAVYA • DATA STRUCTURES

📚 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.

10
20
30
TOP → 30

🧠 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.
Important: In a stack, both insertion and deletion are performed at the same end — TOP.

⚙️ Basic Stack Operations

Push Insert a new element at the top.
Pop Remove and return the top element.
Peek / Top Read the top element without removing it.
isEmpty / isFull Check whether an operation is currently possible.

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.

INTERACTIVE ALGORITHM VISUALIZATION
CodeBhavya CodeBhavya
🎬 Premium Array Stack Visualizer Push multiple values, pop multiple elements, and watch TOP move with the stack
top = 2
← TOP pointer
Choose an operation and press Load Operation.
OperationPush
Elements3
Step1

⬆️ 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
Order matters: increment 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
Important: logically, the element is removed by reducing 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

⚡ Time and Space Complexity

Push — O(1) Only the top index and one array element are updated.
Pop — O(1) Only the current top value and top index are used.
Peek — O(1) Directly reads stack[top].
Space — O(MAX) The fixed array reserves space for MAX elements.
Interview note: Array-based stacks provide O(1) push, pop and peek, but a fixed-size array may cause overflow when the capacity is exhausted.

🔗 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 is the head pointer top always stores the address of the most recently pushed node.
No fixed array capacity The stack grows dynamically while memory allocation succeeds.
Key difference from an array stack: there is no 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
INTERACTIVE ALGORITHM VISUALIZATION
CodeBhavya CodeBhavya
🎬 Premium Linked List Stack Visualizer Push multiple values, pop multiple nodes, and watch the TOP pointer change
top = N3
← TOP / head
Choose an operation and press Prepare Operation.
OperationPush Values
Nodes3
Step1

💻 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

⚡ Linked List Stack Complexity

Push — O(1) Insert the new node directly before the current TOP.
Pop — O(1) Move TOP to the next node and free the old first node.
Peek — O(1) Read top->data directly.
Space — O(n) Each element requires one dynamically allocated node.
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
Interview note: A linked-list stack avoids a fixed array capacity, but every element needs pointer memory and dynamic allocation. The head must be used as TOP to preserve O(1) Push and Pop.

🧩 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.

Opening Bracket For (, {, or [, push it onto the stack.
Closing Bracket For ), }, or ], compare it with the current TOP.
Final Check The expression is balanced only if no mismatch occurred and the stack is empty at the end.

🧠 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
INTERACTIVE ALGORITHM VISUALIZATION
CodeBhavya CodeBhavya
🎬 Premium Parentheses Balancing Visualizer Follow every character, stack Push/Pop, match, and final result
Bracket Stack
Current Character:
Action: Ready
TOP:
Result: Pending
Load an expression and press Next.

💻 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

⚡ Parentheses Balancing Complexity

Time — O(n) Every expression character is processed once.
Push — O(1) Each opening bracket is pushed once.
Pop — O(1) Each matching closing bracket removes at most one stack item.
Auxiliary Space — O(n) In the worst case, all characters may be opening brackets.
Interview note: A balanced-bracket solution must check both order and type. For example, (] 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.

Operand Append it directly to postfix.
Opening ( Push it onto the operator stack.
Closing ) Pop operators until ( is found, then discard the pair.
Operator Pop stronger/equal-precedence operators first, then push the current operator.

Operator Precedence

Operator Meaning Precedence Associativity
^Exponent3Right to Left
* / %Multiply / Divide / Mod2Left to Right
+ -Add / Subtract1Left 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
INTERACTIVE ALGORITHM VISUALIZATION
CodeBhavya CodeBhavya
🎬 Premium Infix to Postfix Visualizer Watch operands move to output and operators move through the stack
Operator Stack
Postfix Output
Current Token:
Action: Ready
TOP:
Load an infix expression and press Next.

💻 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-*+

⚡ Infix to Postfix Complexity

Time — O(n) Each token is processed once and each operator is pushed/popped at most once.
Push — O(1) Operators and opening parentheses are pushed in constant time.
Pop — O(1) Each operator pop is constant time.
Auxiliary Space — O(n) The operator stack can contain O(n) symbols in the worst case.
Interview note: For equal precedence, left-associative operators such as +, -, *, 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.

Operand Convert the digit to an integer and push it.
Operator Pop b, pop a, compute a op b.
Final Result After the scan, exactly one value should remain on the stack.

🧠 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
Important: For subtraction and division, operand order matters. If the stack contains ... a, b, then evaluate a - b or a / b, not the reverse.
INTERACTIVE ALGORITHM VISUALIZATION
CodeBhavya CodeBhavya
🎬 Premium Postfix Evaluation Visualizer Watch operands enter the stack and operators combine the top two values
Value Stack
Current Token:
First Operand (a):
Second Operand (b):
Operation: Ready
Current / Final Result
Load a postfix expression and press Next.

💻 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

⚡ Postfix Evaluation Complexity

Time — O(n) Each postfix token is processed exactly once.
Operand Push — O(1) Each operand is pushed in constant time.
Operator Evaluation — O(1) Each operator performs two pops, one arithmetic operation, and one push.
Auxiliary Space — O(n) The operand stack may hold O(n) values in the worst case.
Interview note: When evaluating an operator, always pop the second operand first. For postfix 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.

1. What is LIFO?
LIFO means Last In, First Out. The element inserted most recently is removed first.
Interview answer: A stack removes elements in the reverse order of insertion.
2. What are stack overflow and stack underflow?
For a fixed array stack, overflow occurs when Push is attempted while top == MAX - 1. Underflow occurs when Pop or Peek is attempted while top == -1.
Interview answer: Overflow means no free stack capacity; underflow means no element is available to remove/read.
3. Why are Push and Pop O(1)?
Both operations work only at the top. They do not traverse the stack or shift all elements. Only a constant number of assignments is required.
Interview answer: Stack operations access only TOP, so the work does not grow with the number of elements.
4. Why should TOP be the head node in a linked-list stack?
Insertion and deletion at the head require only pointer updates, so Push and Pop remain O(1). If TOP were kept at the tail of a singly linked list, Pop would normally need traversal to find the previous node.
Interview answer: Using the head as TOP gives O(1) insertion and deletion in a singly linked stack.
5. What is the main trade-off between an array stack and a linked-list stack?
An array stack is compact and simple but commonly has a fixed capacity. A linked-list stack grows dynamically, but each node stores an additional pointer and requires dynamic memory allocation.
Interview answer: Arrays use less per-element memory; linked stacks provide dynamic size at the cost of pointer and allocation overhead.
6. Why is a stack suitable for parentheses balancing?
The most recently seen unmatched opening bracket must be matched first. That is exactly the Last In, First Out behavior provided by a stack.
Interview answer: The latest unmatched opening bracket must close first, so LIFO matches the required nesting order.
7. Why is counting opening and closing brackets not enough?
Balanced expressions require correct nesting and matching types, not just equal counts. For example, (] contains one opening and one closing bracket but is invalid.
Interview answer: Counts cannot verify nesting order or bracket type; a stack can verify both.
8. Why is postfix easier for a computer to evaluate than infix?
Postfix does not require parentheses or repeated precedence decisions during evaluation. The operator appears only after its operands, so a stack can evaluate the expression in a single scan.
Interview answer: Postfix encodes evaluation order directly, so precedence and parentheses are not needed during evaluation.
9. Why is ^ treated differently when two operators have equal precedence?
Exponentiation is normally right-associative. For A^B^C, the intended grouping is A^(B^C). Therefore an existing ^ of equal precedence should not be popped before pushing the new ^.
Interview answer: Equal-precedence ^ is kept on the stack because exponentiation associates from right to left.
10. Why must the second operand be popped before the first operand in postfix evaluation?
When an operator is reached, the most recently pushed value is the right-hand operand. Therefore the first pop gives b, the second pop gives a, and the expression must be evaluated as a op b.
Interview answer: Stack order makes the first pop the right operand and the second pop the left operand.
11. What condition should hold after a valid postfix expression is fully evaluated?
Exactly one result should remain in the stack. If too many values remain, or an operator tries to pop more operands than available, the postfix expression is invalid.
Interview answer: A valid postfix evaluation ends with exactly one stack value — the final result.

🎯 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.

📈 Stack Practice Progress
Solved 0 / 20
Completed with Solution 0
Total Score 0 / 2000
Completion 0%

🏆 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.

← Previous Topic: Linked-List Next Topic: Queue →