Data Structures - Doubly Linked List
1. Introduction
A doubly linked list (DLL) is a type of linked list in which each node contains:
Data — the value stored in the node.
Prev (previous pointer) — a pointer/reference to the previous node.
Next (next pointer) — a pointer/reference to the next node.
Unlike a singly linked list, a doubly linked list allows traversal in both directions: forward and backward.
2. Structure of a Node
+--------+--------+--------+
| Prev | Data | Next |
+--------+--------+--------+
Prev points to the previous node (or
nullif it's the first node).Next points to the next node (or
nullif it's the last node).Data stores the value (integer, string, object, etc.).
3. Basic Operations
3.1 Create a Doubly Linked List
class Node:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
class DoublyLinkedList:
def __init__(self):
self.head = None
3.2 Insertion
1. Insert at the beginning
def insert_at_head(self, data):
new_node = Node(data)
if self.head:
new_node.next = self.head
self.head.prev = new_node
self.head = new_node
2. Insert at the end
def insert_at_tail(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
current = self.head
while current.next:
current = current.next
current.next = new_node
new_node.prev = current
3. Insert after a given node
def insert_after(self, prev_node, data):
if not prev_node:
return
new_node = Node(data)
new_node.next = prev_node.next
new_node.prev = prev_node
if prev_node.next:
prev_node.next.prev = new_node
prev_node.next = new_node
3.3 Deletion
1. Delete a node by value
def delete_node(self, key):
current = self.head
while current:
if current.data == key:
if current.prev:
current.prev.next = current.next
else:
self.head = current.next
if current.next:
current.next.prev = current.prev
return
current = current.next
3.4 Traversal
1. Forward traversal
def traverse_forward(self):
current = self.head
while current:
print(current.data, end=" <-> ")
current = current.next
print("None")
2. Backward traversal
def traverse_backward(self):
current = self.head
if not current:
return
# go to last node
while current.next:
current = current.next
# traverse backward
while current:
print(current.data, end=" <-> ")
current = current.prev
print("None")
4. Advantages of Doubly Linked List
Can traverse in both directions.
Easier to delete a node if a pointer to it is known.
More flexible insertion and deletion compared to singly linked list.
Disadvantages:
Uses extra memory for the previous pointer.
Slightly more complex to implement than singly linked list.