Doubly Linked List

Back Home

Category

Category: Sequence types

Topics

Topics: pointer manipulation, LRU caches, browser history, undo/redo systems

Definition

A linear data structure where each node contains data and two pointers - one to the next node and one to the previous node - enabling bidirectional traversal.

Use cases

Attributes

Common operations

Operation Time Complexity Description
Access O(n) Traverse from head or tail
Search O(n) Linear scan in either direction
Insert (head) O(1) Update head and its neighbor
Insert (tail) O(1) Update tail and its neighbor
Insert (at node) O(1) Update prev/next pointers
Delete (head) O(1) Update head pointer
Delete (tail) O(1) Update tail pointer
Delete (at node) O(1) Update neighbor pointers

In code

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def append(self, data):
        """Insert at tail - O(1)"""
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
            return
        new_node.prev = self.tail
        self.tail.next = new_node
        self.tail = new_node

    def prepend(self, data):
        """Insert at head - O(1)"""
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
            return
        new_node.next = self.head
        self.head.prev = new_node
        self.head = new_node

    def delete(self, node):
        """Delete given node - O(1)"""
        if node.prev:
            node.prev.next = node.next
        else:
            self.head = node.next
        if node.next:
            node.next.prev = node.prev
        else:
            self.tail = node.prev

    def traverse_forward(self):
        """Traverse head to tail"""
        current = self.head
        while current:
            yield current.data
            current = current.next

    def traverse_backward(self):
        """Traverse tail to head"""
        current = self.tail
        while current:
            yield current.data
            current = current.prev

Time complexity

Space complexity

O(n) for n elements. Each node requires extra space for two pointers (prev and next), typically 16 bytes on 64-bit systems. No auxiliary space for operations.

Trade-offs

Pros:

Cons:

Variants

When to use vs avoid