0
0
DSA Pythonprogramming

Delete by Value in Doubly Linked List in DSA Python

Choose your learning style9 modes available
Mental Model
To remove a node with a specific value, find it by moving through the list, then adjust the links of its neighbors to skip it.
Analogy: Imagine a train with cars linked front and back. To remove a car, you disconnect it from the car before and the car after, then the train continues without that car.
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
↑head
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3 ↔ 4, delete value 3
Goal: Remove the node containing value 3 and keep the list connected
Step 1: start at head node with value 1
null ← [1↑head] ↔ 2 ↔ 3 ↔ 4 -> null
Why: We begin searching from the start to find the node to delete
Step 2: move to next node with value 2
null ← 1 ↔ [2↑] ↔ 3 ↔ 4 -> null
Why: Value 2 is not the target, so continue searching
Step 3: move to next node with value 3 (target found)
null ← 1 ↔ 2 ↔ [3↑] ↔ 4 -> null
Why: Found the node to delete
Step 4: adjust previous node's next to skip 3 and point to 4
null ← 1 ↔ 2 ↔ 4 -> null
Why: By linking 2 directly to 4, node 3 is removed from forward chain
Step 5: adjust next node's prev to skip 3 and point to 2
null ← 1 ↔ 2 ↔ 4 -> null
Why: By linking 4 back to 2, node 3 is removed from backward chain
Result:
null ← 1 ↔ 2 ↔ 4 -> null
Annotated Code
DSA Python
class Node:
    def __init__(self, val):
        self.val = val
        self.prev = None
        self.next = None

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

    def append(self, val):
        new_node = Node(val)
        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 delete_by_value(self, val):
        curr = self.head
        while curr:
            if curr.val == val:
                if curr.prev:
                    curr.prev.next = curr.next  # link previous node to next
                else:
                    self.head = curr.next  # deleting head
                if curr.next:
                    curr.next.prev = curr.prev  # link next node to previous
                return  # delete first occurrence only
            curr = curr.next

    def __str__(self):
        vals = []
        curr = self.head
        while curr:
            vals.append(str(curr.val))
            curr = curr.next
        return ' ↔ '.join(vals) if vals else 'empty list'

# Driver code
dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.append(4)
print("Before deletion:", dll)
dll.delete_by_value(3)
print("After deletion:", dll)
while curr:
traverse nodes to find target value
if curr.val == val:
check if current node holds the value to delete
if curr.prev: curr.prev.next = curr.next
link previous node's next to skip current node
else: self.head = curr.next
if deleting head, update head pointer
if curr.next: curr.next.prev = curr.prev
link next node's prev to skip current node
return
stop after deleting first matching node
OutputSuccess
Before deletion: 1 ↔ 2 ↔ 3 ↔ 4 After deletion: 1 ↔ 2 ↔ 4
Complexity Analysis
Time: O(n) because we may need to check each node once to find the value
Space: O(1) because we only use a few pointers, no extra data structures
vs Alternative: Compared to singly linked list deletion, doubly linked list allows backward link updates, making deletion easier without needing to track previous node separately
Edge Cases
empty list
no deletion occurs, list remains empty
DSA Python
while curr:
value not found
list remains unchanged after full traversal
DSA Python
while curr:
deleting head node
head pointer updates to next node
DSA Python
else:
self.head = curr.next
deleting tail node
previous node's next set to None, tail removed
DSA Python
if curr.next:
curr.next.prev = curr.prev
When to Use This Pattern
When you need to remove a node by value in a list where nodes link both forward and backward, use the delete by value in doubly linked list pattern to adjust both links cleanly.
Common Mistakes
Mistake: Not updating the previous node's next pointer when deleting a middle node
Fix: Always set curr.prev.next = curr.next when curr.prev exists
Mistake: Not updating the next node's prev pointer when deleting a middle node
Fix: Always set curr.next.prev = curr.prev when curr.next exists
Mistake: Not updating head pointer when deleting the first node
Fix: If curr.prev is None, update self.head to curr.next
Summary
Deletes the first node with a given value by adjusting links of neighbors in a doubly linked list.
Use when you want to remove a specific value from a doubly linked list efficiently.
The key is to update both previous and next pointers to bypass the node being deleted.