Insert at Specific Position in Doubly Linked List in DSA C# - Time & Space Complexity
We want to understand how the time to insert a node at a specific position in a doubly linked list changes as the list grows.
How does the number of steps depend on the list size?
Analyze the time complexity of the following code snippet.
public void InsertAtPosition(int position, int data) {
Node newNode = new Node(data);
if (position == 1) {
newNode.Next = Head;
if (Head != null) Head.Prev = newNode;
Head = newNode;
return;
}
Node current = Head;
for (int i = 1; i < position - 1 && current != null; i++) {
current = current.Next;
}
if (current == null) return; // position out of range
newNode.Next = current.Next;
if (current.Next != null) current.Next.Prev = newNode;
current.Next = newNode;
newNode.Prev = current;
}
This code inserts a new node at a given position by first moving to the node before that position, then adjusting pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop that moves through the list nodes to reach the insertion point.
- How many times: Up to position - 2 times, which depends on the input position.
As the position increases, the number of steps to reach that position grows roughly the same.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 8 steps to reach position |
| 100 | Up to 98 steps to reach position |
| 1000 | Up to 998 steps to reach position |
Pattern observation: The time grows linearly with the position number, so larger positions take more steps.
Time Complexity: O(n)
This means the time to insert grows in direct proportion to the position where we insert in the list.
[X] Wrong: "Insertion at any position in a doubly linked list always takes constant time O(1)."
[OK] Correct: You must first find the position by moving through nodes, which takes time proportional to the position, so it is not always constant time.
Understanding this helps you explain how linked lists work and why some operations are fast or slow, a key skill in many coding interviews.
"What if we kept a reference to the tail node and the position is near the end? How would the time complexity change?"
Practice
Solution
Step 1: Understand position 1 in doubly linked list
Position 1 means the start of the list, so the new node should be the first element.Step 2: Insert new node at head
The new node's next pointer points to the old head, and the old head's previous pointer points back to the new node.Final Answer:
The new node becomes the new head of the list. -> Option CQuick Check:
Insert at position 1 = new head [OK]
- Thinking position 1 means end of list
- Ignoring previous pointer update
- Assuming position 1 is invalid
Solution
Step 1: Check method parameter order
The common pattern is to pass the node first, then the position.Step 2: Match method name and parameters
InsertAtPosition(newNode, 3) matches the expected syntax for inserting at position 3.Final Answer:
InsertAtPosition(newNode, 3); -> Option AQuick Check:
Node first, position second = InsertAtPosition(newNode, 3); [OK]
- Swapping parameter order
- Using incorrect method names
- Passing position before node
Solution
Step 1: Identify position 2 in the list
Position 2 means after the first node (10), so new node goes between 10 and 20.Step 2: Insert 15 between 10 and 20
Update pointers: 10's next to 15, 15's previous to 10, 15's next to 20, 20's previous to 15.Final Answer:
10 <-> 15 <-> 20 <-> 30 <-> null -> Option AQuick Check:
Insert at position 2 = between first and second nodes [OK]
- Inserting before first node
- Inserting at wrong position
- Not updating previous pointers
Node newNode = new Node(25);
Node temp = head;
for (int i = 1; i < 2; i++) {
temp = temp.next;
}
newNode.next = temp.next;
newNode.prev = temp;
temp.next.prev = newNode;
temp.next = newNode;Solution
Step 1: Analyze loop and temp position
The loop moves temp to the node at position 2, so temp.next might be null if list ends there.Step 2: Check pointer updates for null safety
Accessing temp.next.prev without checking if temp.next is null can cause a runtime error.Final Answer:
temp.next.prev = newNode; causes null reference if temp.next is null. -> Option BQuick Check:
Check for null before accessing temp.next.prev [OK]
- Ignoring null pointer checks
- Wrong loop range causing off-by-one
- Incorrect pointer assignments
Solution
Step 1: Identify position 3 in the list
Position 3 means the new node should be placed after the second node (10) and before the third node (15).Step 2: Insert node with value 12 between 10 and 15
Update pointers: 10's next to 12, 12's previous to 10, 12's next to 15, 15's previous to 12.Final Answer:
5 <-> 10 <-> 12 <-> 15 <-> 20 <-> null -> Option DQuick Check:
Insert at position 3 places node between second and third nodes [OK]
- Inserting at wrong position
- Not updating both next and prev pointers
- Confusing position numbering
Ready to prove it?
Pass the test and this pattern moves unknown
