{
  "id": "linked-lists/doubly-linked-list",
  "version": 1,
  "deterministic": true,
  "url": "/dsa/linked-lists/doubly-linked-list",
  "topic": {
    "slug": "linked-lists",
    "title": "Linked Lists"
  },
  "title": "Doubly Linked List",
  "tagline": "One extra pointer per node — and the singly linked list's worst flaw disappears.",
  "vizKind": "list",
  "complexity": {
    "time": {
      "best": "O(1) delete a known node",
      "average": "O(n) to find",
      "worst": "O(n) to find"
    },
    "space": "O(n)",
    "growth": "linear",
    "note": "Finding a node still costs O(n) — no indexes, same as before. But once you're holding it, deleting is O(1) instead of requiring a walk. And you can traverse in both directions. The price: an extra pointer per node."
  },
  "code": {
    "javascript": "class Node {\n  constructor(value) {\n    this.value = value;\n    this.prev = null;   // the extra pointer\n    this.next = null;\n  }\n}\n\nfunction remove(node) {\n  // No walk needed — the node knows who is behind it.\n  if (node.prev) node.prev.next = node.next;\n  if (node.next) node.next.prev = node.prev;\n  node.prev = null;\n  node.next = null;\n}",
    "python": "class Node:\n    def __init__(self, value):\n        self.value = value\n        self.prev = None    # the extra pointer\n        self.next = None\n\n\n\ndef remove(node):\n    # No walk needed — the node knows who is behind it.\n    if node.prev: node.prev.next = node.next\n    if node.next: node.next.prev = node.prev\n    node.prev = None\n    node.next = None\n",
    "java": "class Node {\n  int value;\n  Node prev;   // the extra pointer\n  Node next;\n  Node(int value) { this.value = value; }\n}\n\n\nvoid remove(Node node) {\n  // No walk needed — the node knows who is behind it.\n  if (node.prev != null) node.prev.next = node.next;\n  if (node.next != null) node.next.prev = node.prev;\n  node.prev = null;\n  node.next = null;\n}",
    "cpp": "struct Node {\n  int value;\n  Node* prev = nullptr;   // the extra pointer\n  Node* next = nullptr;\n  Node(int v) : value(v) {}\n};\n\n\nvoid remove(Node* node) {\n  // No walk needed — the node knows who is behind it.\n  if (node->prev) node->prev->next = node->next;\n  if (node->next) node->next->prev = node->prev;\n  node->prev = nullptr;\n  node->next = nullptr;\n}"
  },
  "defaultInput": [
    4,
    8,
    15,
    16,
    23
  ],
  "defaultTarget": null,
  "inputHint": "Walk forwards, then backwards, then delete from the middle in one step.",
  "pitfalls": [
    {
      "wrong": "Updating `next` but forgetting `prev`.",
      "right": "The nastiest bug in this structure. Walking forwards still works, so everything looks fine — until someone walks backwards and falls off a broken chain."
    },
    {
      "wrong": "Forgetting the edge cases at the head and tail.",
      "right": "The head has no prev and the tail has no next. Deleting either means null-checking before you dereference, or you crash on the very first or last node."
    },
    {
      "wrong": "Reaching for it when a singly linked list would do.",
      "right": "It costs an extra pointer per node and doubles the bookkeeping. Only pay that if you actually need backward traversal or O(1) deletion of a node you already hold."
    }
  ],
  "quiz": [
    {
      "q": "What does the extra `prev` pointer buy you?",
      "options": [
        "Faster searching",
        "O(1) deletion of a node you're already holding, and backward traversal",
        "Less memory",
        "Automatic sorting"
      ],
      "answer": 1,
      "why": "A node now knows who's behind it, so removing it means re-aiming two arrows — no walk from the head. And you can traverse in both directions, which a singly linked list can't do at all."
    },
    {
      "q": "Does a doubly linked list make *finding* a node faster?",
      "options": [
        "Yes, twice as fast",
        "No — there are still no indexes, so finding is still O(n)",
        "Yes, it's O(1)",
        "Yes, it's O(log n)"
      ],
      "answer": 1,
      "why": "Finding is unchanged: you still walk from an end, one node at a time. Only *deletion once found* got faster. It's a common misconception."
    },
    {
      "q": "What's the sneakiest bug in a doubly linked list?",
      "options": [
        "Running out of memory",
        "Updating `next` but forgetting `prev` — forward walks still work, so it hides",
        "Infinite loops",
        "Losing the head"
      ],
      "answer": 1,
      "why": "A half-updated link leaves the forward chain perfectly intact, so all your normal code passes. The corruption only surfaces when something walks backwards — often much later."
    }
  ],
  "problems": [
    {
      "name": "LRU Cache",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/lru-cache/"
    },
    {
      "name": "Flatten a Multilevel Doubly Linked List",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/"
    },
    {
      "name": "Design Browser History",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/design-browser-history/"
    }
  ],
  "trace": {
    "note": "Each frame is one immutable step: data snapshot, pointers, per-index roles, executing code line, and a one-sentence explanation.",
    "length": 15,
    "frames": [
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          }
        ],
        "highlights": [],
        "codeLine": 1,
        "variables": {
          "length": 5
        },
        "explanation": "A doubly linked list gives every node a second pointer: one to the next node, one to the previous. That's one extra arrow, and it changes everything.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "compare"
          },
          {
            "index": 1,
            "role": "compare"
          },
          {
            "index": 2,
            "role": "compare"
          },
          {
            "index": 3,
            "role": "compare"
          },
          {
            "index": 4,
            "role": "compare"
          }
        ],
        "codeLine": 4,
        "variables": {
          "pointersPerNode": 2
        },
        "explanation": "Every arrow now points both ways. You can walk this list backwards as easily as forwards — try that on a singly linked list and you simply can't.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "direction": "forwards",
          "at": 4
        },
        "explanation": "Walking forwards: 4.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 1
          }
        ],
        "highlights": [
          {
            "index": 1,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "direction": "forwards",
          "at": 8
        },
        "explanation": "Walking forwards: 8.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 2
          }
        ],
        "highlights": [
          {
            "index": 2,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "direction": "forwards",
          "at": 15
        },
        "explanation": "Walking forwards: 15.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 3
          }
        ],
        "highlights": [
          {
            "index": 3,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "direction": "forwards",
          "at": 16
        },
        "explanation": "Walking forwards: 16.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 4
          }
        ],
        "highlights": [
          {
            "index": 4,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "direction": "forwards",
          "at": 23
        },
        "explanation": "Walking forwards: 23.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 4
          }
        ],
        "highlights": [
          {
            "index": 4,
            "role": "pivot"
          }
        ],
        "codeLine": 3,
        "variables": {
          "direction": "backwards",
          "at": 23
        },
        "explanation": "And now backwards, using prev: 23. No walking from the head required.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 3
          }
        ],
        "highlights": [
          {
            "index": 3,
            "role": "pivot"
          }
        ],
        "codeLine": 3,
        "variables": {
          "direction": "backwards",
          "at": 16
        },
        "explanation": "And now backwards, using prev: 16. No walking from the head required.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 2
          }
        ],
        "highlights": [
          {
            "index": 2,
            "role": "pivot"
          }
        ],
        "codeLine": 3,
        "variables": {
          "direction": "backwards",
          "at": 15
        },
        "explanation": "And now backwards, using prev: 15. No walking from the head required.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 1
          }
        ],
        "highlights": [
          {
            "index": 1,
            "role": "pivot"
          }
        ],
        "codeLine": 3,
        "variables": {
          "direction": "backwards",
          "at": 8
        },
        "explanation": "And now backwards, using prev: 8. No walking from the head required.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          },
          {
            "name": "cur",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "pivot"
          }
        ],
        "codeLine": 3,
        "variables": {
          "direction": "backwards",
          "at": 4
        },
        "explanation": "And now backwards, using prev: 4. No walking from the head required.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d2-15",
              "value": 15
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "cur",
            "index": 2
          }
        ],
        "highlights": [
          {
            "index": 1,
            "role": "active"
          },
          {
            "index": 2,
            "role": "found"
          },
          {
            "index": 3,
            "role": "active"
          }
        ],
        "codeLine": 9,
        "variables": {
          "deleting": 15
        },
        "explanation": "Delete 15. In a singly linked list we'd have to walk from the head to find the node *before* it. Here, 15 already knows who's behind it.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 1,
            "role": "swap"
          }
        ],
        "codeLine": 11,
        "variables": {
          "length": 4,
          "steps": 1
        },
        "explanation": "Re-aim two arrows and 15 is gone — in a single step, O(1), with no walk at all. That's what the extra pointer bought.",
        "stats": {
          "comparisons": 0,
          "swaps": 1
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "d0-4",
              "value": 4
            },
            {
              "id": "d1-8",
              "value": 8
            },
            {
              "id": "d3-16",
              "value": 16
            },
            {
              "id": "d4-23",
              "value": 23
            }
          ],
          "doubly": true
        },
        "pointers": [
          {
            "name": "head",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "sorted"
          },
          {
            "index": 1,
            "role": "sorted"
          },
          {
            "index": 2,
            "role": "sorted"
          },
          {
            "index": 3,
            "role": "sorted"
          }
        ],
        "codeLine": 13,
        "variables": {
          "length": 4
        },
        "explanation": "The cost: one extra pointer per node — more memory, and two arrows to keep correct on every insert and delete. Forget one, and the list quietly falls apart.",
        "stats": {
          "comparisons": 0,
          "swaps": 1
        }
      }
    ]
  }
}