Insert at Beginning of Doubly Linked List in DSA Python - 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.
class Node:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
class DoublyLinkedList:
def __init__(self):
self.head = None
def insert_at_beginning(self, data):
new_node = Node(data)
new_node.next = self.head
if self.head is not None:
self.head.prev = new_node
self.head = new_node
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 at the start.
- How many times: These pointer assignments happen once per insertion, no loops or recursion.
Each insertion requires the same fixed number of steps, no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 3-4 pointer assignments |
| 100 | 3-4 pointer assignments |
| 1000 | 3-4 pointer assignments |
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 large 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 touch the other nodes.
Knowing that insertion at the start of a doubly linked list is quick helps you explain efficient data structure operations clearly.
"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 operation
Inserting at the beginning means adding a new node before the current first node.Step 2: Identify the purpose
This operation makes the new node the first element in the doubly linked list.Final Answer:
To add a new node as the first element of the list -> Option AQuick Check:
Insert at beginning = Add new first node [OK]
- Confusing insertion at beginning with deletion
- Thinking it reverses the list
- Assuming it finds a node instead of adding
Solution
Step 1: Create new node and link next pointer
new_node.next should point to current head to place it before head.Step 2: Update previous head's prev pointer and head reference
head.prev must point back to new_node, then update head to new_node.Final Answer:
new_node = Node(data); new_node.next = head; head.prev = new_node; head = new_node -> Option CQuick Check:
New node next = head, head prev = new node [OK]
- Swapping prev and next pointers
- Not updating head to new node
- Forgetting to update old head's prev pointer
class Node:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
head = Node(20)
new_node = Node(10)
new_node.next = head
head.prev = new_node
head = new_node
# Print list forward
current = head
result = []
while current:
result.append(current.data)
current = current.next
print(result)Solution
Step 1: Insert 10 before 20
New node with data 10 points next to old head (20), old head prev points back to new node.Step 2: Traverse from new head and collect data
Starting at head (10), next is 20, then None. So list is [10, 20].Final Answer:
[10, 20] -> Option BQuick Check:
List after insertion = [10, 20] [OK]
- Confusing order and printing reversed list
- Not updating head pointer
- Printing only one node
new_node = Node(5) new_node.next = head head = new_node head.prev = new_node
Solution
Step 1: Analyze pointer assignments
new_node.next points to old head (correct), but head = new_node happens before head.prev = new_node.Step 2: Identify the error
By the time head.prev = new_node executes, head is already the new_node, creating a self-loop. The old head's prev is never set. head.prev must be set before updating head to link the old head back correctly.Final Answer:
head.prev should be set before updating head -> Option AQuick Check:
Update old head.prev before head = new_node [OK]
- Setting prev pointer after head update incorrectly
- Making first node's prev point to itself
- Ignoring prev pointer for head node
Solution
Step 1: Insert 20 at beginning
New node 20 points next to 30, 30 prev points to 20. List becomes 20 <-> 30 <-> 40 <-> 50.Step 2: Insert 10 at beginning
New node 10 points next to 20, 20 prev points to 10. List becomes 10 <-> 20 <-> 30 <-> 40 <-> 50.Final Answer:
10 <-> 20 <-> 30 <-> 40 <-> 50 -> Option DQuick Check:
Insertions add nodes at front in order [OK]
- Inserting nodes in wrong order
- Appending instead of prepending
- Not updating prev pointers correctly
Ready to prove it?
Pass the test and this pattern moves unknown
