Double Ended Queue Deque in DSA C - Time & Space Complexity
We want to understand how fast operations on a double ended queue (deque) run as the number of items grows.
Specifically, how does adding or removing items from either end affect the time it takes?
Analyze the time complexity of the following code snippet.
// Simple deque operations
void pushFront(Deque* dq, int val) {
// Add val at front
dq->front = (dq->front - 1 + dq->capacity) % dq->capacity;
dq->arr[dq->front] = val;
dq->size++;
}
int popBack(Deque* dq) {
// Remove from back
int val = dq->arr[(dq->front + dq->size - 1) % dq->capacity];
dq->size--;
return val;
}
This code adds an item at the front and removes an item from the back of a deque implemented with a circular array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Simple index calculations and direct array access.
- How many times: Each operation runs once per call, no loops or recursion inside.
Each push or pop does a fixed number of steps regardless of how many items are in the deque.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5-6 steps |
| 100 | 5-6 steps |
| 1000 | 5-6 steps |
Pattern observation: The number of steps stays the same no matter how big the deque is.
Time Complexity: O(1)
This means adding or removing items from either end takes the same short time no matter how many items are stored.
[X] Wrong: "Removing from the back of a deque takes longer as it gets bigger because you have to shift items."
[OK] Correct: The deque uses a circular array with index math, so no shifting is needed. Each remove or add is a quick step.
Knowing that deque operations run in constant time shows you understand efficient data structures, a key skill in coding interviews and real projects.
"What if the deque was implemented using a linked list instead of an array? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of Deque
A Deque allows adding and removing elements from both front and rear ends.Step 2: Compare with other data structures
Unlike a queue or stack, Deque supports operations at both ends.Final Answer:
A data structure where insertion and deletion can happen at both ends -> Option BQuick Check:
Deque = Both ends insertion/deletion [OK]
- Confusing deque with stack or queue
- Thinking insertion is only at one end
- Assuming random access like arrays
Solution
Step 1: Understand initialization of deque with front and rear
Front and rear are set to -1 to indicate empty deque.Step 2: Check array declaration and initial values
int deque[SIZE]; int front = -1, rear = -1; correctly declares array and sets front and rear to -1.Final Answer:
int deque[SIZE]; int front = -1, rear = -1; -> Option CQuick Check:
Empty deque front and rear = -1 [OK]
- Setting front or rear to 0 initially
- Using NULL for array initialization
- Leaving array size unspecified
insertRear(10); insertRear(20); insertFront(5); deleteRear(); insertFront(15);What is the content of the deque from front to rear after these operations?
Solution
Step 1: Perform insertRear(10) and insertRear(20)
Deque: 10 -> 20Step 2: Perform insertFront(5)
Deque: 5 -> 10 -> 20Step 3: Perform deleteRear()
Removes 20, Deque: 5 -> 10Step 4: Perform insertFront(15)
Deque: 15 -> 5 -> 10Final Answer:
15 -> 5 -> 10 -> null -> Option AQuick Check:
Operations result in 15,5,10 order [OK]
- Forgetting deleteRear removes last element
- Mixing order of insertFront and insertRear
- Assuming insertFront adds at rear
void insertFront(int deque[], int *front, int *rear, int value) {
if (*front == 0) {
printf("Deque is full at front\n");
return;
}
(*front)--;
deque[*front] = value;
}Solution
Step 1: Analyze the full condition check
Checking only if front == 0 is not enough to detect full deque.Step 2: Understand circular deque logic
Deque can be full even if front != 0, so this check is incomplete.Final Answer:
It incorrectly checks full condition only at front == 0 -> Option AQuick Check:
Full check must consider rear position too [OK]
- Assuming front == 0 means full always
- Not handling circular wrap-around
- Decrementing front without boundary check
insertRear(1); insertRear(2); insertFront(3); insertFront(4); deleteRear(); insertRear(5);What is the final state of the deque from front to rear?
Solution
Step 1: InsertRear(1), InsertRear(2)
Deque: 1 -> 2Step 2: InsertFront(3), InsertFront(4)
Deque: 4 -> 3 -> 1 -> 2 (deque full)Step 3: DeleteRear()
Removes 2, Deque: 4 -> 3 -> 1Step 4: InsertRear(5)
Deque: 4 -> 3 -> 1 -> 5 (full again)Final Answer:
4 -> 3 -> 1 -> 5 -> null -> Option DQuick Check:
Circular deque final state matches 4 -> 3 -> 1 -> 5 -> null [OK]
- Ignoring circular wrap-around
- Misordering front and rear elements
- Forgetting deleteRear removes last element
Ready to prove it?
Pass the test and this pattern moves unknown
