Insert at Beginning of Doubly Linked List in DSA C - Time & Space Complexity
We want to understand how the time needed to insert a new node at the start of a doubly linked list changes as the list grows.
Specifically, how does the work change when the list gets longer?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
void insertAtBeginning(struct Node** head, int newData) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = newData;
newNode->prev = NULL;
newNode->next = *head;
if (*head != NULL) {
(*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.
- How many times: Only once per insertion, no loops or repeated traversals.
Adding a node at the start always takes the same steps, no matter how long the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 5 steps |
| 100 | About 5 steps |
| 1000 | About 5 steps |
Pattern observation: The number of steps stays the same regardless of list size.
Time Complexity: O(1)
This means inserting at the beginning takes a constant amount of time no matter how big the list is.
[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; we do not move or visit other nodes.
Knowing that insertion at the start is quick helps you explain efficient list operations clearly and confidently.
"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 structure of a doubly linked list
A doubly linked list has nodes connected both forward and backward, with a head and tail.Step 2: Identify what inserting at the beginning means
Inserting at the beginning means adding a new node before the current head node, making it the new head.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
- Thinking insertion deletes nodes
- Mixing up head and tail positions
Solution
Step 1: Identify pointer updates when inserting at beginning
The new node's next points to old head, and old head's prev points back to new node.Step 2: Choose correct pointer update for old head
We must set old_head->prev = new_node to link backward to new node.Final Answer:
old_head->prev = new_node; -> Option DQuick Check:
Old head prev points to new node [OK]
- Setting old_head->next instead of prev
- Assigning new_node->prev incorrectly
- Forgetting to update old head's prev pointer
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
Node* head = NULL;
void insertAtBeginning(int val) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = val;
new_node->prev = NULL;
new_node->next = head;
if (head != NULL) {
head->prev = new_node;
}
head = new_node;
}
int main() {
insertAtBeginning(20);
insertAtBeginning(10);
Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
return 0;
}Solution
Step 1: Trace first insertion insertAtBeginning(20)
List is empty, new node with 20 becomes head: 20 -> NULLStep 2: Trace second insertion insertAtBeginning(10)
New node with 10 points next to old head (20), old head prev points to new node, head updated to 10: 10 <-> 20Final Answer:
10 20 -> Option CQuick Check:
List after insertions = 10 20 [OK]
- Printing nodes in reverse order
- Not updating head pointer
- Forgetting to update old head's prev pointer
void insertAtBeginning(int val) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = val;
new_node->prev = NULL;
new_node->next = head;
if (head != NULL) {
head->next = new_node;
}
head = new_node;
}Solution
Step 1: Check pointer updates for old head
When inserting at beginning, old head's prev pointer must point to new node, not next.Step 2: Identify incorrect line
Code uses head->next = new_node; which wrongly sets old head's next pointer instead of prev.Final Answer:
head->next should be head->prev when updating old head -> Option AQuick Check:
Old head prev must point to new node [OK]
- Updating old head's next pointer instead of prev
- Not updating head pointer
- Incorrect malloc size usage
Solution
Step 1: Understand insertion at beginning
New node with value 1 becomes new head, pointing next to old head (5).Step 2: Update pointers and traverse list
Sequence after insertion: 1 (head) <-> 5 <-> 15 <-> 25 (tail).Final Answer:
1 <-> 5 <-> 15 <-> 25 -> Option AQuick Check:
New head is 1, followed by old nodes [OK]
- Appending new node at end instead of beginning
- Mixing node order after insertion
- Not updating head pointer
Ready to prove it?
Pass the test and this pattern moves unknown
