Insert at End of Doubly Linked List in DSA C++ - Time & Space Complexity
We want to understand how the time to insert a new node at the end of a doubly linked list changes as the list grows.
How does the number of steps needed grow when the list gets longer?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
Node* prev;
Node* next;
};
void insertAtEnd(Node*& head, int val) {
Node* newNode = new Node{val, nullptr, nullptr};
if (!head) {
head = newNode;
return;
}
Node* temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
This code inserts a new node with value val at the end of a doubly linked list starting at head.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
whileloop that moves through the list to find the last node. - How many times: It runs once for each node until the end, so roughly
ntimes if the list hasnnodes.
As the list gets longer, the loop takes more steps to reach the end.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps to reach the end |
| 100 | About 100 steps to reach the end |
| 1000 | About 1000 steps to reach the end |
Pattern observation: The number of steps grows directly with the size of the list.
Time Complexity: O(n)
This means the time to insert at the end grows linearly with the number of nodes in the list.
[X] Wrong: "Inserting at the end is always fast and takes constant time."
[OK] Correct: Without a pointer to the last node, you must walk through the whole list, which takes longer as the list grows.
Understanding this helps you explain how linked lists work and why keeping track of the tail node can speed up insertions.
"What if we kept a pointer to the last node (tail) of the list? How would the time complexity change?"
Practice
Solution
Step 1: Understand the structure of a doubly linked list
A doubly linked list has nodes connected forward and backward, allowing traversal in both directions.Step 2: Purpose of insertion at the end
Inserting at the end means adding a new node after the current last node, updating pointers accordingly.Final Answer:
To add a new element after the last node -> Option AQuick Check:
Insert at end = Add after last node [OK]
- Confusing insertion at end with deletion
- Thinking insertion at end reverses the list
- Assuming insertion happens at the start
Solution
Step 1: Identify the new tail after insertion
When a new node is added at the end, it becomes the new tail of the list.Step 2: Update the tail pointer
Assign the tail pointer to point to the new node to reflect the updated end of the list.Final Answer:
tail = newNode; -> Option DQuick Check:
New tail points to newNode [OK]
- Setting tail to previous node instead of new node
- Resetting tail to head incorrectly
- Assigning tail to NULL after insertion
struct Node {
int data;
Node* prev;
Node* next;
};
Node* head = new Node{10, NULL, NULL};
Node* tail = head;
Node* newNode = new Node{30, tail, NULL};
tail->next = newNode;
tail = newNode;
// Print list from head
Node* temp = head;
while(temp != NULL) {
std::cout << temp->data << " ";
temp = temp->next;
}Solution
Step 1: Initial list and insertion
Initially, list has one node with data 10. New node with 30 is added at end, linked properly.Step 2: Traversing and printing
Starting from head (10), print data then move to next node (30), print data, then NULL ends loop.Final Answer:
10 30 -> Option AQuick Check:
List after insertion = 10 30 [OK]
- Printing nodes in reverse order
- Not updating tail->next pointer
- Forgetting to update tail pointer
void insertEnd(Node*& head, Node*& tail, int val) {
Node* newNode = new Node{val, NULL, NULL};
if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
newNode->prev = tail;
head = newNode; // Error here
}
}Solution
Step 1: Analyze pointer updates in else block
tail->next points to newNode and newNode->prev points to tail correctly.Step 2: Identify incorrect pointer assignment
head is wrongly updated to newNode; it should remain unchanged. Instead, tail should be updated to newNode.Final Answer:
tail should be updated to newNode -> Option CQuick Check:
Tail points to last node after insertion [OK]
- Updating head instead of tail
- Not linking newNode's prev pointer
- Forgetting to set tail->next
Solution
Step 1: Insert 20 at the end
Starting list: 5 <-> 10 <-> 15. After inserting 20 at end: 5 <-> 10 <-> 15 <-> 20.Step 2: Insert 2 at the end
Now add 2 at end: 5 <-> 10 <-> 15 <-> 20 <-> 2.Final Answer:
5 <-> 10 <-> 15 <-> 20 <-> 2 -> Option BQuick Check:
Insertions add nodes at list end in order [OK]
- Inserting new nodes at the start instead of end
- Mixing order of inserted nodes
- Confusing next and prev pointers
Ready to prove it?
Pass the test and this pattern moves unknown
