Dequeue Using Linked List in DSA C++ - Time & Space Complexity
We want to understand how fast operations run in a dequeue built with a linked list.
Specifically, how the time to add or remove items changes as the number of items grows.
Analyze the time complexity of the following code snippet.
struct Node {
int data;
Node* next;
Node* prev;
};
class Dequeue {
Node* front;
Node* rear;
public:
void insertFront(int x) {
Node* temp = new Node{x, front, nullptr};
if (front) front->prev = temp;
front = temp;
if (!rear) rear = temp;
}
void deleteRear() {
if (!rear) return;
Node* temp = rear;
rear = rear->prev;
if (rear) rear->next = nullptr;
else front = nullptr;
delete temp;
}
};
This code shows how to add an item at the front and remove an item from the rear in a dequeue using a doubly linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding or removing a node involves only a few pointer changes.
- How many times: Each operation runs once per call, no loops or recursion inside.
Each insert or delete operation takes the same small number of steps no matter how many items are in the dequeue.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 3-5 pointer changes |
| 100 | 3-5 pointer changes |
| 1000 | 3-5 pointer changes |
Pattern observation: The time stays about the same no matter how many items are in the dequeue.
Time Complexity: O(1)
This means adding or removing items from either end takes a constant amount of time regardless of size.
[X] Wrong: "Removing from the rear takes longer because we have to find the last node."
[OK] Correct: The linked list keeps a direct pointer to the rear node, so no searching is needed.
Knowing that dequeue operations run in constant time shows you understand efficient data structure design.
This skill helps you explain and write fast code for real problems.
"What if we used a singly linked list without a rear pointer? How would the time complexity of deleting from the rear change?"
Practice
Dequeue using a linked list over an array?Solution
Step 1: Understand Dequeue operations
A dequeue allows insertion and deletion from both front and rear ends.Step 2: Compare linked list and array
Linked list supports O(1) insertion/deletion at both ends without shifting, unlike arrays.Final Answer:
It allows insertion and deletion from both ends in O(1) time without shifting elements. -> Option AQuick Check:
Linked list dequeue = O(1) insert/delete both ends [OK]
- Thinking arrays allow O(1) insert/delete at both ends
- Assuming linked list sorts elements automatically
- Confusing memory usage advantages
Solution
Step 1: Create new node with data
We allocate a new node and assign the data to it.Step 2: Link new node to current front and update front pointer
Set newNode->next to current front, then update front to newNode.Final Answer:
void insertFront(int data) { Node* newNode = new Node(data); newNode->next = front; front = newNode; } -> Option BQuick Check:
New node points to old front, front updated [OK]
- Assigning data directly to front pointer
- Deleting front before inserting
- Not linking new node to old front
Dequeue dq; dq.insertRear(10); dq.insertFront(20); dq.insertRear(30); dq.deleteFront(); dq.insertFront(40); dq.deleteRear(); dq.display();What will be the output of
dq.display()?Solution
Step 1: Trace insertions and deletions step-by-step
insertRear(10): 10 insertFront(20): 20 -> 10 insertRear(30): 20 -> 10 -> 30 deleteFront(): removes 20, now 10 -> 30 insertFront(40): 40 -> 10 -> 30 deleteRear(): removes 30, now 40 -> 10Step 2: Final list after all operations
40 -> 10 -> nullFinal Answer:
40 -> 10 -> null -> Option AQuick Check:
Trace insert/delete carefully for final list [OK]
- Forgetting to update front or rear after deletion
- Mixing order of insertFront and insertRear
- Assuming deleted elements remain
void deleteRear() {
if (rear == nullptr) return;
Node* temp = front;
while (temp->next != rear) {
temp = temp->next;
}
delete rear;
rear = temp;
rear->next = nullptr;
}
What is the bug in this code?Solution
Step 1: Analyze the loop for single node case
If only one node exists, front == rear, so while loop condition temp->next != rear fails immediately, temp = front.Step 2: Check what happens after loop
Deleting rear node, then setting rear = temp (which is front). But if only one node, temp == rear, so deleting rear deletes the only node, then rear points to deleted memory, causing dangling pointer.Final Answer:
It does not handle the case when there is only one node in the dequeue. -> Option CQuick Check:
Single node case needs special handling [OK]
- Ignoring single-node edge case
- Assuming loop always runs at least once
- Not updating rear pointer correctly
reverseDequeue() that reverses the order of elements in a dequeue implemented using a linked list. Which approach is best to reverse the dequeue efficiently?Solution
Step 1: Reverse linked list pointers in one traversal
Reversing next pointers of each node in one pass efficiently reverses the list.Step 2: Swap front and rear pointers
After reversal, front and rear pointers must be swapped to reflect new ends.Final Answer:
Traverse the linked list once, reversing the next pointers of each node, then swap front and rear pointers. -> Option DQuick Check:
In-place reversal with pointer swap is most efficient [OK]
- Using extra memory unnecessarily
- Re-inserting nodes instead of reversing pointers
- Not swapping front and rear after reversal
Ready to prove it?
Pass the test and this pattern moves unknown
