doublyLinkedList.definition

doublyLinkedList.descriptionPart1

doublyLinkedList.descriptionPart2

doublyLinkedList.keyPointsTitle

  • doublyLinkedList.keyPoint1
  • doublyLinkedList.keyPoint2
  • doublyLinkedList.keyPoint3
  • doublyLinkedList.keyPoint4

doublyLinkedList.exampleTitle

null ←
10doublyLinkedList.headLabel
20
30
40doublyLinkedList.tailLabel
→ null

doublyLinkedList.syntaxTitle

// Java
class Node {
    int value;
    Node prev;
    Node next;

    Node(int value) {
        this.value = value;
    }
}

class DoublyLinkedList {
    Node head;
    Node tail;

    void insert(int value) {
        Node node = new Node(value);
        if (head == null) {
            head = tail = node;
        } else {
            tail.next = node;
            node.prev = tail;
            tail = node;
        }
    }
}
# Python
class Node:
    def __init__(self, value):
        self.value = value
        self.prev = None
        self.next = None

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

    def insert(self, value):
        node = Node(value)
        if not self.head:
            self.head = self.tail = node
        else:
            self.tail.next = node
            node.prev = self.tail
            self.tail = node
// C++
struct Node {
    int value;
    Node* prev;
    Node* next;
    Node(int v) : value(v), prev(nullptr), next(nullptr) {}
};

class DoublyLinkedList {
public:
    Node* head = nullptr;
    Node* tail = nullptr;

    void insert(int value) {
        Node* node = new Node(value);
        if (!head) {
            head = tail = node;
        } else {
            tail->next = node;
            node->prev = tail;
            tail = node;
        }
    }
};
// JavaScript
class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class DoublyLinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }

  insert(value) {
    const node = new Node(value);
    if (!this.head) {
      this.head = this.tail = node;
    } else {
      this.tail.next = node;
      node.prev = this.tail;
      this.tail = node;
    }
  }
}

Interactive Doubly Linked List Visualization

List is empty. Insert a value to begin.

Size: 0
Node
Traversing
Found
Inserting
Rewiring
Removing

Note: Each node has both prev and next pointers. Insert at tail is O(1) with tail pointer. Remove/Search traverse from head O(n).

Time & Space Complexity

Doubly linked lists allow O(1) insertion/removal at both ends and enable backward traversal, at the cost of extra memory for the prev pointer.

OperationTimeWhy?
Insert at TailO(1)With tail pointer, directly append and update prev/next
Insert at HeadO(1)Update head pointer and set new node's next to old head
Remove (by value)O(n)Traverse to find node, then O(1) to rewire pointers
Remove Head/TailO(1)Direct access via head/tail pointers
SearchO(n)Traverse nodes one by one (can go forward or backward)
Access by IndexO(n)Must traverse from head or tail
SpaceO(n)Extra pointer (prev) per node compared to singly linked list

vs Singly Linked List

  • Advantage: Can traverse backward and remove tail in O(1)
  • Advantage: Easier deletion when you have a pointer to the node
  • Disadvantage: Extra memory per node for prev pointer
  • Disadvantage: Slightly more complex insert/remove logic

enhanced.relatedTopics.prerequisites

enhanced.relatedTopics.related

enhanced.relatedTopics.advanced

doublyLinkedList.continueLearning

enhanced.author.title

enhanced.author.writtenBy:enhanced.author.teamName
enhanced.author.reviewedBy:enhanced.author.reviewerName
enhanced.author.lastUpdated:January 29, 2026