Bird
Raised Fist0
DSA Cprogramming

Queue Using Two Stacks in DSA C

Choose your learning style10 modes available
Mental Model
Use two stacks to mimic the behavior of a queue by reversing order twice.
Analogy: Imagine two trays where you put plates in one tray stacked on top, then move them to the second tray to reverse order, so you can take plates out in the order they were put in.
stack1: top -> [3] [2] [1]
stack2: top -> [1] [2] [3]
queue front is at bottom of stack1 but accessible via stack2 after transfer
Dry Run Walkthrough
Input: enqueue 1, enqueue 2, enqueue 3, dequeue, enqueue 4, dequeue
Goal: Show how two stacks work together to enqueue and dequeue in FIFO order
Step 1: enqueue 1: push 1 onto stack1
stack1: [1]
stack2: []
Why: New elements go into stack1 to keep insertion order
Step 2: enqueue 2: push 2 onto stack1
stack1: [2, 1]
stack2: []
Why: Keep adding new elements on top of stack1
Step 3: enqueue 3: push 3 onto stack1
stack1: [3, 2, 1]
stack2: []
Why: Stack1 holds all new elements in order
Step 4: dequeue: stack2 empty, move all from stack1 to stack2 reversing order
stack1: []
stack2: [1, 2, 3]
Why: Reversing stack1 into stack2 makes oldest element accessible on top
Step 5: dequeue: pop top of stack2 (1)
stack1: []
stack2: [2, 3]
Why: Remove oldest element from queue
Step 6: enqueue 4: push 4 onto stack1
stack1: [4]
stack2: [2, 3]
Why: New elements always go to stack1
Step 7: dequeue: pop top of stack2 (2)
stack1: [4]
stack2: [3]
Why: Continue removing from stack2 until empty
Result:
stack1: [4]
stack2: [3]
Dequeued elements in order: 1, 2
Annotated Code
DSA C
#include <stdio.h>
#include <stdlib.h>

#define MAX 100

typedef struct Stack {
    int arr[MAX];
    int top;
} Stack;

void initStack(Stack* s) {
    s->top = -1;
}

int isEmpty(Stack* s) {
    return s->top == -1;
}

int isFull(Stack* s) {
    return s->top == MAX - 1;
}

void push(Stack* s, int val) {
    if (isFull(s)) {
        printf("Stack overflow\n");
        return;
    }
    s->arr[++(s->top)] = val;
}

int pop(Stack* s) {
    if (isEmpty(s)) {
        printf("Stack underflow\n");
        return -1;
    }
    return s->arr[(s->top)--];
}

typedef struct Queue {
    Stack s1;
    Stack s2;
} Queue;

void initQueue(Queue* q) {
    initStack(&q->s1);
    initStack(&q->s2);
}

void enqueue(Queue* q, int val) {
    push(&q->s1, val); // push new element onto s1
}

int dequeue(Queue* q) {
    if (isEmpty(&q->s2)) { // if s2 empty, move all from s1 to s2
        while (!isEmpty(&q->s1)) {
            int x = pop(&q->s1); // pop from s1
            push(&q->s2, x);     // push onto s2
        }
    }
    return pop(&q->s2); // pop from s2 is dequeue
}

int main() {
    Queue q;
    initQueue(&q);

    enqueue(&q, 1);
    enqueue(&q, 2);
    enqueue(&q, 3);

    printf("Dequeued: %d\n", dequeue(&q));

    enqueue(&q, 4);

    printf("Dequeued: %d\n", dequeue(&q));

    return 0;
}
push(&q->s1, val); // push new element onto s1
add new element to stack1 to keep insertion order
if (isEmpty(&q->s2)) { while (!isEmpty(&q->s1)) { int x = pop(&q->s1); push(&q->s2, x); } }
transfer all elements from stack1 to stack2 to reverse order when stack2 empty
return pop(&q->s2); // pop from s2 is dequeue
remove and return the oldest element from stack2
OutputSuccess
Dequeued: 1 Dequeued: 2
Complexity Analysis
Time: O(1) amortized for enqueue and dequeue because each element is moved at most twice between stacks
Space: O(n) because all elements are stored in two stacks combined
vs Alternative: Compared to a linked list queue with O(1) enqueue and dequeue, this uses two stacks and may have occasional O(n) transfer but amortized O(1)
Edge Cases
dequeue from empty queue
returns -1 and prints underflow message
DSA C
if (isEmpty(&q->s2)) { ... } return pop(&q->s2);
enqueue after some dequeues
new elements go to stack1 without affecting stack2 until stack2 empties
DSA C
push(&q->s1, val);
all elements dequeued, then enqueue new elements
stack2 empty triggers transfer from stack1 on next dequeue
DSA C
if (isEmpty(&q->s2)) { while (!isEmpty(&q->s1)) { ... } }
When to Use This Pattern
When you need to implement a queue but only have stack operations, use two stacks to reverse order twice and simulate FIFO behavior.
Common Mistakes
Mistake: Trying to dequeue directly from stack1 without transferring to stack2
Fix: Always transfer elements from stack1 to stack2 when stack2 is empty before dequeue
Mistake: Transferring elements from stack1 to stack2 on every dequeue
Fix: Only transfer when stack2 is empty to keep amortized O(1) complexity
Summary
Implements a queue using two stacks by reversing element order twice.
Use when only stack operations are allowed but queue behavior is needed.
The key is transferring elements from one stack to another only when needed to maintain correct order.

Practice

(1/5)
1. What is the main idea behind implementing a Queue Using Two Stacks?
easy
A. Use two stacks to store elements in sorted order
B. Use two stacks to reverse the order twice to maintain queue order
C. Use one stack for enqueue and another for dequeue operations
D. Use two stacks to perform only enqueue operations

Solution

  1. Step 1: Understand queue order

    A queue follows FIFO (First In First Out) order, meaning the first element added is the first to be removed.
  2. Step 2: Use two stacks to reverse order twice

    One stack reverses the order when pushing elements, and the second stack reverses it again when popping, restoring FIFO order.
  3. Final Answer:

    Use two stacks to reverse the order twice to maintain queue order -> Option B
  4. Quick Check:

    Two reversals keep FIFO order [OK]
Hint: Two stacks reverse order twice to simulate queue [OK]
Common Mistakes:
  • Thinking both stacks store elements in sorted order
  • Using stacks only for enqueue or dequeue, not both
  • Confusing stack order with queue order
2. Which of the following is the correct syntax to push an element x onto a stack named stack1 in C?
easy
A. push(stack1, x);
B. stack1.push(x); // C syntax
C. stack1.push(x);
D. push(x, stack1);

Solution

  1. Step 1: Recall stack push function in C

    In C, stacks are usually implemented with functions like push(stack, element).
  2. Step 2: Identify correct argument order

    The stack is passed first, then the element to push, so push(stack1, x) is correct.
  3. Final Answer:

    push(stack1, x); -> Option A
  4. Quick Check:

    Function call with stack first, element second [OK]
Hint: In C, push(stack, element) is standard [OK]
Common Mistakes:
  • Using object.method() syntax which is not valid in C
  • Swapping argument order in push function
  • Assuming push is a built-in method
3. Consider the following code snippet implementing a queue using two stacks s1 and s2. What will be the output after the operations?
push(s1, 10);
push(s1, 20);
pop(s2);
if (isEmpty(s2)) {
  while (!isEmpty(s1)) {
    push(s2, top(s1));
pop(s1);
  }
}
pop(s2);
printQueue(s1, s2);
medium
A. Queue elements: 10 -> null
B. Queue elements: null
C. Queue elements: 20 -> null
D. Queue elements: 10 -> 20 -> null

Solution

  1. Step 1: Push 10 and 20 onto s1

    s1 = [10 (bottom), 20 (top)], s2 = []
  2. Step 2: Pop from s2 (empty), then transfer all from s1 to s2

    Transfer reverses order: s2 = [20 (bottom), 10 (top)], s1 = []
  3. Step 3: Pop from s2 removes 10 (top)

    s2 = [20]
  4. Step 4: printQueue shows elements in queue order

    Queue order is s2 top to bottom then s1 bottom to top, so only 20 remains.
  5. Final Answer:

    Queue elements: 20 -> null -> Option C
  6. Quick Check:

    First popped element was 10, next is 20 [OK]
Hint: Transfer reverses stack order to simulate queue dequeue [OK]
Common Mistakes:
  • Not transferring elements from s1 to s2 when s2 is empty
  • Confusing top and bottom elements during transfer
  • Assuming pop removes from s1 directly
4. The following code attempts to implement dequeue operation in a queue using two stacks s1 and s2. What is the bug?
int dequeue() {
  if (isEmpty(s2)) {
    while (!isEmpty(s1)) {
      push(s2, top(s1));
      pop(s1);
    }
  }
  return pop(s2);
}
medium
A. Missing check if both stacks are empty before dequeue
B. pop(s2) returns void, should use top(s2) before pop
C. Should push from s2 to s1 instead of s1 to s2
D. pop(s1) should be called after push(s2, top(s1))

Solution

  1. Step 1: Check for empty queue condition

    The code does not check if both s1 and s2 are empty before dequeue, which can cause errors.
  2. Step 2: Identify missing empty check

    Without this check, pop(s2) may be called on empty stack causing runtime error.
  3. Final Answer:

    Missing check if both stacks are empty before dequeue -> Option A
  4. Quick Check:

    Empty queue must be handled before popping [OK]
Hint: Always check if queue is empty before dequeue [OK]
Common Mistakes:
  • Assuming pop returns the popped value in C without checking
  • Ignoring empty queue condition
  • Confusing push direction between stacks
5. You want to implement a queue using two stacks s1 and s2. You perform the following operations:
enqueue(1);
enqueue(2);
dequeue();
enqueue(3);
dequeue();
dequeue();

What will be the output sequence of the dequeued elements?
hard
A. [3, 2, 1]
B. [1, 3, 2]
C. [2, 1, 3]
D. [1, 2, 3]

Solution

  1. Step 1: Enqueue 1 and 2

    s1 = [1 (bottom), 2 (top)], s2 = []
  2. Step 2: Dequeue first element

    s2 empty, transfer all from s1 to s2: s2 = [2 (bottom), 1 (top)], s1 = []
    Pop from s2 removes 1
  3. Step 3: Enqueue 3

    Push 3 to s1: s1 = [3], s2 = [2]
  4. Step 4: Dequeue second element

    s2 not empty, pop from s2 removes 2
  5. Step 5: Dequeue third element

    s2 empty, transfer s1 to s2: s2 = [3], s1 = []
    Pop from s2 removes 3
  6. Final Answer:

    [1, 2, 3] -> Option D
  7. Quick Check:

    FIFO order maintained by two stacks [OK]
Hint: Dequeue triggers transfer only if second stack empty [OK]
Common Mistakes:
  • Not transferring elements when s2 is empty
  • Assuming enqueue adds to s2 instead of s1
  • Mixing order of popped elements
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard