Queue vs Stack When to Use Which in DSA C - Complexity Comparison
We want to understand how the time it takes to use a queue or a stack changes as we add more items.
Which one is faster or better for certain tasks?
Analyze the time complexity of the following code snippet.
// Simple stack push and pop
void stackOperations(int n) {
int stack[n];
int top = -1;
for (int i = 0; i < n; i++) {
stack[++top] = i; // push operation
}
while (top >= 0) {
int val = stack[top--]; // pop operation
}
}
// Simple queue enqueue and dequeue
void queueOperations(int n) {
int queue[n];
int front = 0, rear = -1;
for (int i = 0; i < n; i++) {
queue[++rear] = i; // enqueue operation
}
while (front <= rear) {
int val = queue[front++]; // dequeue operation
}
}
This code shows basic push/pop for stack and enqueue/dequeue for queue with n items.
Both stack and queue perform repeated operations:
- Primary operation: push and pop for stack; enqueue and dequeue for queue.
- How many times: Each operation runs exactly n times, once per item.
As the number of items n grows, the total operations grow in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 20 (10 pushes + 10 pops) |
| 100 | 200 (100 pushes + 100 pops) |
| 1000 | 2000 (1000 pushes + 1000 pops) |
Pattern observation: Operations increase directly with n, doubling because each item is added and then removed.
Time Complexity: O(n)
This means the time to process all items grows in a straight line with the number of items.
[X] Wrong: "Stacks or queues take longer time as they get bigger because of complex operations inside."
[OK] Correct: Both stack and queue operations here are simple and happen once per item, so time grows linearly, not more.
Understanding when to use stack or queue and their time costs helps you choose the right tool for problems and explain your choices clearly.
"What if we used a linked list instead of an array for the queue? How would the time complexity change?"
Practice
Solution
Step 1: Understand the order of processing tasks
Tasks arriving in order and processed in the same order means First-In-First-Out (FIFO).Step 2: Match FIFO with the correct data structure
Queue follows FIFO, so it fits the scenario of customers waiting in line.Final Answer:
Queue, because it processes elements in First-In-First-Out order -> Option AQuick Check:
FIFO = Queue [OK]
- Confusing FIFO with LIFO
- Choosing Stack for ordered processing
- Thinking arrays maintain insertion order automatically
Solution
Step 1: Recall typical C stack function syntax
In C, stack operations are usually functions taking the stack and element as arguments.Step 2: Identify correct function call order
push(stack, element) is the standard way to push an element onto a stack in C.Final Answer:
push(stack, element); -> Option DQuick Check:
Function call with stack first = push(stack, element) [OK]
- Using object.method() syntax which is not C style
- Swapping argument order in function call
- Assuming stack is a pointer with methods
#include
#include
#define MAX 5
typedef struct {
int items[MAX];
int top;
} Stack;
void push(Stack *s, int val) {
if (s->top == MAX - 1) return;
s->items[++s->top] = val;
}
int pop(Stack *s) {
if (s->top == -1) return -1;
return s->items[s->top--];
}
int main() {
Stack s;
s.top = -1;
push(&s, 10);
push(&s, 20);
push(&s, 30);
printf("%d ", pop(&s));
printf("%d ", pop(&s));
return 0;
}
Solution
Step 1: Trace push operations on stack
Push 10, stack: [10]; push 20, stack: [10,20]; push 30, stack: [10,20,30]. Top points to 30.Step 2: Trace pop operations and output
First pop returns 30, second pop returns 20, so output is "30 20 ".Final Answer:
30 20 -> Option BQuick Check:
LIFO pop order = 30 then 20 [OK]
- Assuming FIFO order for stack
- Mixing push and pop order
- Ignoring initial top = -1
#include
#define MAX 3
int queue[MAX];
int front = -1, rear = -1;
void enqueue(int val) {
if (rear == MAX - 1) {
printf("Queue full\n");
return;
}
queue[++rear] = val;
if (front == -1) front = 0;
}
int dequeue() {
if (front == -1 || front > rear) {
printf("Queue empty\n");
return -1;
}
return queue[front++];
}
int main() {
enqueue(1);
enqueue(2);
enqueue(3);
dequeue();
enqueue(4);
printf("%d\n", queue[rear]);
return 0;
}
Solution
Step 1: Understand enqueue and dequeue behavior
Enqueue adds at rear, dequeue removes from front. After dequeueing all, front > rear but variables not reset.Step 2: Identify problem with overflow after dequeue
After dequeueing, rear stays at max index, so enqueue thinks queue is full even if space is free.Final Answer:
The queue does not reset front and rear after dequeueing all elements, causing overflow -> Option CQuick Check:
Queue pointers not reset = overflow bug [OK]
- Ignoring front and rear reset after emptying queue
- Thinking enqueue index is wrong
- Assuming dequeue returns wrong element
Solution
Step 1: Understand undo/redo operation order
Undo reverses last action (LIFO), redo re-applies undone actions in reverse order.Step 2: Choose data structures matching LIFO behavior
Two stacks allow pushing actions for undo and redo separately, supporting LIFO order for both.Final Answer:
Two stacks: one for undo and one for redo, because stacks support LIFO order needed for undo/redo -> Option AQuick Check:
Undo/Redo = Two stacks (LIFO) [OK]
- Using queues which are FIFO, not suitable for undo
- Ignoring redo functionality
- Using only one stack which can't handle redo
Ready to prove it?
Pass the test and this pattern moves unknown
