Create and Initialize Doubly Linked List in DSA Python - Time & Space Complexity
When we create and initialize a doubly linked list, we want to know how the time it takes grows as we add more items.
We ask: How does the work increase when the list gets longer?
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, values):
self.head = None
self.tail = None
for value in values:
new_node = Node(value)
if not self.head:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
new_node.prev = self.tail
self.tail = new_node
This code creates a doubly linked list from a list of values by adding nodes one by one at the end.
- Primary operation: Looping through each value in the input list to create and link nodes.
- How many times: Exactly once for each value in the input list.
Each new value causes one node to be created and linked, so the work grows directly with the number of values.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 node creations and links |
| 100 | About 100 node creations and links |
| 1000 | About 1000 node creations and links |
Pattern observation: The work increases evenly as the list gets longer, doubling the input doubles the work.
Time Complexity: O(n)
This means the time to create the list grows in a straight line with the number of items you add.
[X] Wrong: "Creating the list takes the same time no matter how many items there are."
[OK] Correct: Each item requires a new node and linking, so more items mean more work.
Understanding how creating a linked list scales helps you explain your code clearly and shows you know how data structures behave as they grow.
"What if we added nodes at the front instead of the end? How would the time complexity change?"
Practice
Solution
Step 1: Understand node structure in doubly linked list
Each node in a doubly linked list contains two pointers: one to the next node and one to the previous node.Step 2: Compare with singly linked list
A singly linked list node has only one pointer to the next node, so it can only be traversed forward.Final Answer:
A doubly linked list has nodes with pointers to both next and previous nodes. -> Option CQuick Check:
Doubly linked list nodes have two pointers = C [OK]
- Thinking doubly linked list uses arrays
- Assuming it can only go forward
- Confusing head pointer presence
Solution
Step 1: Identify required attributes for doubly linked list node
A doubly linked list node must have data, a pointer to the next node, and a pointer to the previous node.Step 2: Check each option for completeness
class Node: def __init__(self, data): self.data = data self.next = None self.prev = None correctly defines data, next, and prev attributes initialized properly.Final Answer:
class Node with data, next, and prev attributes initialized -> Option AQuick Check:
Node needs data, next, prev = A [OK]
- Omitting prev pointer
- Omitting data attribute
- Defining next and prev but missing data
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.head = None
def append(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
def display_forward(self):
current = self.head
result = []
while current:
result.append(current.data)
current = current.next
return result
dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
print(dll.display_forward())Solution
Step 1: Append nodes 1, 2, 3 to the doubly linked list
Nodes are added at the end. First node 1 becomes head, then 2 is linked after 1, then 3 after 2.Step 2: Display nodes forward
Starting from head, nodes are visited in order 1 -> 2 -> 3, collected in list [1, 2, 3].Final Answer:
[1, 2, 3] -> Option DQuick Check:
Appending nodes in order shows [1, 2, 3] [OK]
- Confusing order of nodes
- Printing empty list if head is null
- Mixing up forward and backward traversal
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.head = None
def append(self, data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.next = last
Solution
Step 1: Analyze append method's linking logic
After finding last node, code sets last.next = new_node correctly, but sets new_node.next = last, which is wrong.Step 2: Correct backward link pointer
Backward link should be new_node.prev = last, not new_node.next = last.Final Answer:
new_node.next should be new_node.prev to link backward -> Option AQuick Check:
Backward link uses prev pointer = D [OK]
- Setting new_node.next instead of new_node.prev
- Forgetting to link backward pointer
- Confusing next and prev pointers
Solution
Step 1: Append values 10, 20, 30 to doubly linked list
Values are appended in order, head points to 10, last node is 30.Step 2: Move to last node by traversing next pointers
Start at head, move forward while current.next exists to reach last node (30).Step 3: Print backward by moving prev pointers
From last node, print data and move backward using current.prev until null.Final Answer:
Traverse forward to the last node using next pointers, then print backward using prev pointers, producing 30 20 10 -> Option BQuick Check:
Traverse next to last, then prev backward = A [OK]
- Trying to move backward from head
- Using next pointer to go backward
- Not moving to last node before backward print
Ready to prove it?
Pass the test and this pattern moves unknown
