0
0
DSA Pythonprogramming

Doubly Linked List Structure and Node Design in DSA Python

Choose your learning style9 modes available
Mental Model
A doubly linked list is a chain of nodes where each node knows both its neighbor before and after it.
Analogy: Imagine a train where each carriage has a connector to the carriage in front and the one behind, so you can move forward or backward easily.
null ← [head]1↔2↔3[tail] -> null
Dry Run Walkthrough
Input: Create a doubly linked list with nodes 1, 2, 3 linked in order
Goal: Build the doubly linked list so each node points to the next and previous nodes correctly
Step 1: Create node 1 with prev=null and next=null
null ← [1] -> null
Why: Start with the first node which has no neighbors yet
Step 2: Create node 2 and link node 1's next to node 2, node 2's prev to node 1
null ← [1] ↔ [2] -> null
Why: Connect second node so first node points forward and second points back
Step 3: Create node 3 and link node 2's next to node 3, node 3's prev to node 2
null ← [1] ↔ [2] ↔ [3] -> null
Why: Connect third node so the chain extends both ways
Result:
null ← 1 ↔ 2 ↔ 3 -> null
Annotated Code
DSA Python
class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = 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
        curr = self.head
        while curr.next:
            curr = curr.next
        curr.next = new_node
        new_node.prev = curr

    def print_list(self):
        curr = self.head
        result = []
        while curr:
            result.append(str(curr.data))
            curr = curr.next
        print(" ↔ ".join(result))

# Driver code
dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.print_list()
new_node = Node(data)
Create a new node with given data
if not self.head: self.head = new_node return
If list empty, new node becomes head
while curr.next: curr = curr.next
Traverse to the last node
curr.next = new_node new_node.prev = curr
Link new node after last node, set backward link
while curr: result.append(str(curr.data)) curr = curr.next
Traverse from head to tail collecting data for print
OutputSuccess
1 ↔ 2 ↔ 3
Complexity Analysis
Time: O(n) because appending requires traversing to the end of the list
Space: O(n) because each node stores data and two pointers
vs Alternative: Compared to singly linked list, doubly linked list uses more space but allows backward traversal
Edge Cases
Empty list
Appending first node sets head correctly
DSA Python
if not self.head:
    self.head = new_node
    return
Single node list
Appending second node links both nodes forward and backward
DSA Python
curr = self.head
while curr.next:
    curr = curr.next
When to Use This Pattern
When you need to move forward and backward through a list easily, use a doubly linked list structure.
Common Mistakes
Mistake: Forgetting to set the new node's prev pointer when appending
Fix: Always set new_node.prev = curr after linking curr.next = new_node
Mistake: Not handling empty list case when appending
Fix: Check if head is None and set head to new node before traversal
Summary
It creates a chain of nodes where each node links to the next and previous nodes.
Use it when you want to move both forward and backward through a list easily.
Remember each node has two pointers: one to the next node and one to the previous node.