Insert at Beginning of Doubly Linked List in DSA Go - Time & Space Complexity
We want to understand how long it takes to add a new item at the start of a doubly linked list.
How does the time needed change as the list grows bigger?
Analyze the time complexity of the following code snippet.
// Insert new node at the beginning
func InsertAtBeginning(head **Node, data int) {
newNode := &Node{data: data}
newNode.next = *head
if *head != nil {
(*head).prev = newNode
}
*head = newNode
}
This code adds a new node at the start of a doubly linked list by adjusting pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Assigning pointers to link the new node.
- How many times: This happens only once per insertion, no loops or recursion.
Adding a node at the start takes the same steps no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 4 pointer assignments |
| 100 | 4 pointer assignments |
| 1000 | 4 pointer assignments |
Pattern observation: The number of steps stays the same regardless of list size.
Time Complexity: O(1)
This means adding at the start takes a fixed 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 had 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 AQuick Check:
Insert at beginning = add before head [OK]
- Confusing beginning with end insertion
- Thinking insertion deletes nodes
- Assuming insertion reverses list
Solution
Step 1: Identify pointer to update
When inserting at beginning, old head's previous pointer must point to new node.Step 2: Correct assignment
Setting oldHead.prev = newNode correctly links old head back to new node.Final Answer:
oldHead.prev = newNode -> Option BQuick Check:
Old head prev points to new node [OK]
- Assigning newNode.prev incorrectly
- Mixing next and prev pointers
- Updating oldHead.next instead of prev
type Node struct {
data int
prev *Node
next *Node
}
func insertAtBeginning(head **Node, data int) {
newNode := &Node{data: data}
newNode.next = *head
if *head != nil {
(*head).prev = newNode
}
*head = newNode
}
func main() {
var head *Node
insertAtBeginning(&head, 10)
insertAtBeginning(&head, 20)
insertAtBeginning(&head, 30)
// Print list from head
curr := head
for curr != nil {
fmt.Print(curr.data, " -> ")
curr = curr.next
}
fmt.Print("null")
}
What is the printed output?Solution
Step 1: Trace insertions order
Nodes inserted in order: 10, then 20 at beginning, then 30 at beginning.Step 2: List after insertions
After all insertions, list is 30 (head) -> 20 -> 10 -> null.Final Answer:
30 -> 20 -> 10 -> null -> Option DQuick Check:
Last inserted node is new head [OK]
- Assuming insertion adds at end
- Confusing order of nodes
- Ignoring pointer updates
func insertAtBeginning(head *Node, data int) {
newNode := &Node{data: data}
newNode.next = head
head.prev = newNode
head = newNode
}
What is the main error causing the panic?Solution
Step 1: Check nil pointer usage
If head is nil, accessing head.prev causes runtime panic (nil pointer dereference).Step 2: Identify cause of panic
Function does not check if head is nil before head.prev = newNode, causing panic.Final Answer:
head is nil and head.prev causes nil pointer dereference -> Option AQuick Check:
Accessing prev on nil head causes panic [OK]
- Ignoring nil check before pointer access
- Thinking assignment head = newNode updates caller
- Assuming data field causes panic
Solution
Step 1: Understand insertion at beginning
New node with value 3 is added before current head (5).Step 2: Update pointers and traverse
After insertion, list is 3 (head) -> 5 -> 10 -> 15 -> null.Final Answer:
3 -> 5 -> 10 -> 15 -> null -> Option CQuick Check:
New node becomes new head [OK]
- Inserting at end instead of beginning
- Reversing node order incorrectly
- Not updating head pointer
Ready to prove it?
Pass the test and this pattern moves unknown
