Insert at Beginning of Doubly Linked List in DSA C++ - Time & Space Complexity
We want to know how the time to insert a new node at the start of a doubly linked list changes as the list grows.
How does the number of steps grow when the list gets bigger?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
Node* prev;
Node* next;
};
void insertAtBeginning(Node*& head, int value) {
Node* newNode = new Node{value, nullptr, head};
if (head != nullptr) {
head->prev = newNode;
}
head = newNode;
}
This code creates a new node and inserts it at the start of the doubly linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Creating and linking one new node at the start.
- How many times: This happens once per insertion, no loops or recursion involved.
Adding a node at the beginning always takes the same number of steps, no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5 steps |
| 100 | 5 steps |
| 1000 | 5 steps |
Pattern observation: The number of steps stays the same as the list grows.
Time Complexity: O(1)
This means inserting at the start takes a constant amount of time regardless of list size.
[X] Wrong: "Inserting at the beginning takes longer as the list grows because we have to move all nodes."
[OK] Correct: We only change a few pointers at the start; no need to move or visit other nodes.
Knowing that insertion at the start is quick helps you choose the right data structure for fast updates.
"What if we changed this to insert at the end of the doubly linked list without a tail pointer? How would the time complexity change?"
Practice
Solution
Step 1: Understand the head node position
The head node is the first node in the doubly linked list.Step 2: Insert new node before head
Inserting at the beginning means placing the new node before the current head and updating pointers.Final Answer:
To add a new node before the current head node -> Option BQuick Check:
Insert at beginning = Add before head [OK]
- Confusing insertion at beginning with insertion at end
- Not updating the previous head's previous pointer
- Trying to delete instead of insert
Solution
Step 1: Create new node with pointer
Use pointer syntax: Node* newNode = new Node(data);Step 2: Update pointers for doubly linked list
Set newNode->next to current head, update head->prev to newNode, then update head to newNode.Final Answer:
Node* newNode = new Node(data); head->prev = newNode; newNode->next = head; head = newNode; -> Option AQuick Check:
Correct pointer updates = Node* newNode = new Node(data); head->prev = newNode; newNode->next = head; head = newNode; [OK]
- Using object instead of pointer for new node
- Not updating head->prev pointer
- Swapping next and prev pointers incorrectly
struct Node {
int data;
Node* prev;
Node* next;
Node(int d) : data(d), prev(nullptr), next(nullptr) {}
};
Node* head = new Node(20);
head->next = new Node(30);
head->next->prev = head;
Node* newNode = new Node(10);
newNode->next = head;
head->prev = newNode;
head = newNode;
// Print list from head
Node* temp = head;
while(temp) {
std::cout << temp->data << " -> ";
temp = temp->next;
}
std::cout << "null";
Solution
Step 1: Initial list setup
List initially: 20 <-> 30, head points to 20.Step 2: Insert 10 at beginning
New node 10 points next to 20, 20's prev points to 10, head updated to 10.Step 3: Print list from head
Traverse from head: 10 -> 20 -> 30 -> nullFinal Answer:
10 -> 20 -> 30 -> null -> Option CQuick Check:
New head is 10, followed by 20 and 30 [OK]
- Not updating head pointer after insertion
- Incorrect pointer assignments causing wrong order
- Printing from tail instead of head
void insertAtBeginning(Node*& head, int data) {
Node* newNode = new Node(data);
newNode->next = head;
head->prev = newNode;
head = newNode;
}Solution
Step 1: Analyze pointer usage
Code accesses head->prev without checking if head is nullptr (empty list).Step 2: Identify potential runtime error
If head is nullptr, accessing head->prev causes a crash (null pointer dereference).Final Answer:
Missing check if head is nullptr before accessing head->prev -> Option DQuick Check:
Always check head != nullptr before head->prev [OK]
- Ignoring nullptr checks causing crashes
- Incorrect pointer assignments for prev
- Passing head by value instead of reference
Solution
Step 1: Initial list
List is 5 -> 15 -> 25 -> null.Step 2: Insert 1 at beginning
New head is 1, list becomes 1 -> 5 -> 15 -> 25 -> null.Step 3: Insert 35 at beginning
New head is 35, list becomes 35 -> 1 -> 5 -> 15 -> 25 -> null.Final Answer:
35 -> 1 -> 5 -> 15 -> 25 -> null -> Option AQuick Check:
Last inserted node is new head [OK]
- Inserting nodes at end instead of beginning
- Not updating head pointer after each insertion
- Mixing order of inserted nodes
Ready to prove it?
Pass the test and this pattern moves unknown
