Bird
Raised Fist0
DSA Pythonprogramming

Delete by Value in Doubly Linked List in DSA Python

Choose your learning style10 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.

Practice

(1/5)
1. What happens when you delete a node by value in a doubly linked list?
easy
A. The list is reversed instead of deleting
B. All nodes are deleted regardless of value
C. Only the first node is deleted always
D. The node with the matching value is removed and links are updated

Solution

  1. Step 1: Locate the node with the given value

    Traverse the list from head to tail to find the node whose data matches the value to delete.
  2. Step 2: Update links to remove the node

    Adjust the previous node's next pointer and the next node's previous pointer to bypass the node to be deleted.
  3. Final Answer:

    The node with the matching value is removed and links are updated -> Option D
  4. Quick Check:

    Delete by value means remove matching node [OK]
Hint: Find node, update previous and next pointers [OK]
Common Mistakes:
  • Not updating both previous and next pointers
  • Deleting all nodes instead of one
  • Ignoring the case when node is head or tail
2. Which of the following is the correct syntax to delete a node by value in a doubly linked list in Python?
easy
A. def delete_by_value(self, value): current = self.head while current: if current.data == value: # update links break current = current.next
B. def delete_by_value(value): current = head while current: if current.data = value: # update links break current = current.next
C. def delete_by_value(self, value): current = self.head while current: if current.data == value # update links break current = current.next
D. def delete_by_value(self, value): current = self.head while current: if current.data == value: # update links continue current = current.next

Solution

  1. Step 1: Check method signature and loop

    def delete_by_value(self, value): current = self.head while current: if current.data == value: # update links break current = current.next correctly defines a method with self and value, and uses a while loop to traverse nodes.
  2. Step 2: Verify condition and syntax

    def delete_by_value(self, value): current = self.head while current: if current.data == value: # update links break current = current.next uses '==' for comparison and breaks after deletion logic, which is correct syntax and logic.
  3. Final Answer:

    Option A has correct syntax and logic for deletion by value -> Option A
  4. Quick Check:

    Correct method and loop syntax [OK]
Hint: Use '==' for comparison and break after deletion [OK]
Common Mistakes:
  • Using '=' instead of '==' in condition
  • Missing colon ':' after if statement
  • Not including self parameter in method
3. What will be the output of the following code after deleting value 20?
class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

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

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last

    def delete_by_value(self, value):
        current = self.head
        while current:
            if current.data == value:
                if current.prev:
                    current.prev.next = current.next
                else:
                    self.head = current.next
                if current.next:
                    current.next.prev = current.prev
                break
            current = current.next

    def print_list(self):
        current = self.head
        result = []
        while current:
            result.append(current.data)
            current = current.next
        print(result)

dll = DoublyLinkedList()
dll.append(10)
dll.append(20)
dll.append(30)
dll.delete_by_value(20)
dll.print_list()
medium
A. [10]
B. [10, 20, 30]
C. [10, 30]
D. [20, 30]

Solution

  1. Step 1: Append nodes 10, 20, 30

    The list becomes 10 <-> 20 <-> 30.
  2. Step 2: Delete node with value 20

    Node 20 is found and removed by updating 10's next to 30 and 30's prev to 10.
  3. Final Answer:

    [10, 30] -> Option C
  4. Quick Check:

    Deleted 20, list is [10, 30] [OK]
Hint: After deletion, list skips removed value [OK]
Common Mistakes:
  • Not updating head when deleting first node
  • Not updating prev pointer of next node
  • Printing list before deletion
4. Identify the error in the following delete_by_value method for a doubly linked list:
def delete_by_value(self, value):
    current = self.head
    while current:
        if current.data == value:
            current.prev.next = current.next
            current.next.prev = current.prev
            break
        current = current.next
medium
A. Does not traverse the list correctly
B. Does not handle deletion when current is head (current.prev is None)
C. Uses break instead of continue after deletion
D. Deletes all nodes with the value instead of one

Solution

  1. Step 1: Check handling of head node deletion

    If current is head, current.prev is None, so current.prev.next causes error.
  2. Step 2: Confirm missing condition for head update

    Code does not update self.head when deleting the first node, causing attribute error.
  3. Final Answer:

    Does not handle deletion when current is head (current.prev is None) -> Option B
  4. Quick Check:

    Head deletion needs special handling [OK]
Hint: Check if node is head before updating prev pointer [OK]
Common Mistakes:
  • Not checking if current.prev is None
  • Assuming all nodes have prev and next
  • Forgetting to update head pointer
5. Given a doubly linked list with nodes 5 <-> 10 <-> 15 <-> 20, what will be the list after deleting value 5 and then value 20?
hard
A. [10, 15]
B. [5, 10, 15, 20]
C. [15]
D. [10, 15, 20]

Solution

  1. Step 1: Delete node with value 5 (head)

    After deleting 5, head moves to 10, list is 10 <-> 15 <-> 20.
  2. Step 2: Delete node with value 20 (tail)

    After deleting 20, 15 becomes tail, list is 10 <-> 15.
  3. Final Answer:

    [10, 15] -> Option A
  4. Quick Check:

    Deleted head and tail nodes correctly [OK]
Hint: Delete head and tail carefully, update pointers [OK]
Common Mistakes:
  • Not updating head after deleting first node
  • Not updating tail after deleting last node
  • Deleting nodes in wrong order
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard