Bird
Raised Fist0
DSA C#programming

Delete by Value in Doubly Linked List in DSA C#

Choose your learning style10 modes available
Mental Model
We find the node with the value and remove it by linking its neighbors directly to each other.
Analogy: Imagine a train with cars linked together. Removing a car means connecting the car before it directly to the car after it, skipping the removed car.
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
                 ↑
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3 ↔ 4, delete value 3
Goal: Remove the node with value 3 and keep the list connected
Step 1: start at head node with value 1
null ← [1] ↔ 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 1 is not 3, so continue searching
Step 3: move to next node with value 3
null ← 1 ↔ 2 ↔ [3] ↔ 4 -> null
Why: Found the node with value 3 to delete
Step 4: link node 2's next to node 4 and node 4's prev to node 2, removing node 3
null ← 1 ↔ 2 ↔ 4 -> null
Why: By skipping node 3, we remove it and keep the list connected
Result:
null ← 1 ↔ 2 ↔ 4 -> null
Annotated Code
DSA C#
using System;

public class DoublyLinkedListNode
{
    public int Value;
    public DoublyLinkedListNode Prev;
    public DoublyLinkedListNode Next;

    public DoublyLinkedListNode(int value)
    {
        Value = value;
        Prev = null;
        Next = null;
    }
}

public class DoublyLinkedList
{
    public DoublyLinkedListNode Head;

    public DoublyLinkedList()
    {
        Head = null;
    }

    public void Append(int value)
    {
        var newNode = new DoublyLinkedListNode(value);
        if (Head == null)
        {
            Head = newNode;
            return;
        }
        var curr = Head;
        while (curr.Next != null)
        {
            curr = curr.Next;
        }
        curr.Next = newNode;
        newNode.Prev = curr;
    }

    public void DeleteByValue(int value)
    {
        var curr = Head;
        while (curr != null)
        {
            if (curr.Value == value)
            {
                if (curr.Prev != null)
                {
                    curr.Prev.Next = curr.Next; // link previous node to next
                }
                else
                {
                    Head = curr.Next; // deleting head node
                }
                if (curr.Next != null)
                {
                    curr.Next.Prev = curr.Prev; // link next node to previous
                }
                return; // node deleted, exit
            }
            curr = curr.Next; // move to next node
        }
    }

    public void PrintList()
    {
        var curr = Head;
        while (curr != null)
        {
            Console.Write(curr.Value);
            if (curr.Next != null)
                Console.Write(" ↔ ");
            curr = curr.Next;
        }
        Console.WriteLine();
    }
}

public class Program
{
    public static void Main()
    {
        var list = new DoublyLinkedList();
        list.Append(1);
        list.Append(2);
        list.Append(3);
        list.Append(4);

        list.DeleteByValue(3);
        list.PrintList();
    }
}
while (curr != null)
traverse nodes to find the target value
if (curr.Value == value)
check if current node has the value to delete
if (curr.Prev != null) { curr.Prev.Next = curr.Next; } else { Head = curr.Next; }
link previous node to next or update head if deleting first node
if (curr.Next != null) { curr.Next.Prev = curr.Prev; }
link next node back to previous node
return;
stop after deleting the first matching node
curr = curr.Next;
move to next node to continue search
OutputSuccess
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 and no extra data structures
vs Alternative: Compared to singly linked list deletion, doubly linked list allows backward linking, so deletion is simpler without needing to track previous node separately
Edge Cases
empty list
no deletion occurs, list remains empty
DSA C#
while (curr != null)
delete head node
head pointer updates to next node
DSA C#
else { Head = curr.Next; }
delete tail node
previous node's next pointer set to null
DSA C#
if (curr.Next != null) { curr.Next.Prev = curr.Prev; }
value not found
list remains unchanged
DSA C#
while (curr != null)
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 neighbors' pointers safely.
Common Mistakes
Mistake: Not updating the previous node's next pointer when deleting a middle node
Fix: Set curr.Prev.Next = curr.Next to maintain forward links
Mistake: Not updating the next node's prev pointer when deleting a middle node
Fix: Set curr.Next.Prev = curr.Prev to maintain backward links
Mistake: Not handling deletion of the head node separately
Fix: Update Head to curr.Next when deleting the first node
Summary
Deletes the first node with the given value by reconnecting its 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 link the previous and next nodes directly, skipping the node to delete.

Practice

(1/5)
1. What happens when you delete a node by value in a doubly linked list if the value is not found?
easy
A. An error is thrown and the program stops.
B. The first node is deleted regardless of the value.
C. All nodes are deleted from the list.
D. The list remains unchanged because no node matches the value.

Solution

  1. Step 1: Search for the node with the given value

    Traverse the list from head to tail to find a node matching the value.
  2. Step 2: Check if node is found

    If no node matches the value, no deletion occurs and the list stays the same.
  3. Final Answer:

    The list remains unchanged because no node matches the value. -> Option D
  4. Quick Check:

    Delete by value with no match = no change [OK]
Hint: If value not found, list stays same [OK]
Common Mistakes:
  • Assuming deletion happens even if value not found
  • Trying to delete head without checking value
  • Expecting an error instead of no action
2. Which of the following is the correct way to update the previous pointer when deleting a middle node in a doubly linked list in C#?
easy
A. nodeToDelete.Next.Prev = nodeToDelete.Prev;
B. nodeToDelete.Prev.Next = nodeToDelete.Next.Prev;
C. nodeToDelete.Next = nodeToDelete.Prev.Next;
D. nodeToDelete.Prev = nodeToDelete.Next.Prev;

Solution

  1. Step 1: Understand pointers in doubly linked list

    When deleting a node, the next node's previous pointer must point to the deleted node's previous node.
  2. Step 2: Correct pointer update

    Setting nodeToDelete.Next.Prev = nodeToDelete.Prev correctly links the next node back to the previous node.
  3. Final Answer:

    nodeToDelete.Next.Prev = nodeToDelete.Prev; -> Option A
  4. Quick Check:

    Update next node's Prev to deleted node's Prev [OK]
Hint: Next node's Prev points to deleted node's Prev [OK]
Common Mistakes:
  • Mixing up Next and Prev pointers
  • Assigning Prev to Next's Prev incorrectly
  • Not updating both Next and Prev pointers
3. Given the doubly linked list: 10 <-> 20 <-> 30 <-> 40 <-> null, what is the list after deleting the node with value 30?
medium
A. 10 <-> 20 <-> 30 <-> 40 <-> null
B. 10 <-> 20 <-> 40 <-> null
C. 20 <-> 30 <-> 40 <-> null
D. 10 <-> 30 <-> 40 <-> null

Solution

  1. Step 1: Locate node with value 30

    Traverse the list and find the node containing 30 between 20 and 40.
  2. Step 2: Remove node 30 and update pointers

    Set 20's Next to 40 and 40's Prev to 20, skipping 30.
  3. Final Answer:

    10 <-> 20 <-> 40 <-> null -> Option B
  4. Quick Check:

    Deleted 30, linked 20 and 40 directly [OK]
Hint: Remove node, link previous and next nodes [OK]
Common Mistakes:
  • Not updating both Prev and Next pointers
  • Leaving deleted node in the list
  • Deleting wrong node by mistake
4. Consider this code snippet for deleting a node by value in a doubly linked list:
if (current == null) return;
if (current.Prev != null) current.Prev.Next = current.Next;
if (current.Next != null) current.Next.Prev = current.Prev;
if (current == head) head = current.Next;
What is the bug in this code?
medium
A. It may cause a null reference if current is null before checks.
B. It does not update the head when deleting the first node.
C. It does not handle deleting the last node correctly.
D. It does not remove the node from memory.

Solution

  1. Step 1: Verify null safety

    The initial check if (current == null) return; and conditional pointer accesses prevent null references.
  2. Step 2: Check head and pointer updates

    Head is updated correctly when deleting the first node, and pointers are linked properly for middle nodes.
  3. Step 3: Identify the issue with last node

    The code sets current.Prev.Next = null but does not update a potential tail pointer to current.Prev, leaving the tail pointing to the deleted node.
  4. Final Answer:

    It does not handle deleting the last node correctly. -> Option C
  5. Quick Check:

    Missing tail update for last node deletion [OK]
Hint: Update tail pointer when deleting last node [OK]
Common Mistakes:
  • Ignoring null checks before pointer access
  • Not updating head when deleting first node
  • Assuming garbage collection removes node immediately
5. You have a doubly linked list with nodes: 5 <-> 10 <-> 15 <-> 20 <-> 25 <-> null. You want to delete all nodes with values greater than 15. Which approach correctly deletes these nodes by value?
hard
A. Traverse from head, delete nodes with value > 15, updating pointers carefully.
B. Delete nodes by value without updating pointers, then reset head.
C. Only delete the first node with value > 15 and stop.
D. Traverse from tail, delete nodes with value < 15.

Solution

  1. Step 1: Traverse list from head to tail

    Visit each node and check if its value is greater than 15.
  2. Step 2: Delete matching nodes and update pointers

    For each node with value > 15, remove it by linking its previous node to its next node, updating both Next and Prev pointers.
  3. Step 3: Continue traversal carefully

    After deletion, continue traversal without skipping nodes to delete all matching nodes.
  4. Final Answer:

    Traverse from head, delete nodes with value > 15, updating pointers carefully. -> Option A
  5. Quick Check:

    Delete all matching nodes with pointer updates [OK]
Hint: Traverse and delete nodes carefully, update pointers [OK]
Common Mistakes:
  • Deleting nodes without updating pointers
  • Stopping after first deletion
  • Deleting wrong nodes by incorrect condition
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