Bird
Raised Fist0
DSA Goprogramming

Delete by Value in Doubly Linked List in DSA Go

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. To remove one car, you uncouple it and connect the previous car directly to the next 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 2 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: unlink node 3 by connecting node 2's next to node 4 and node 4's prev to node 2
null ← 1 ↔ 2 ↔ 4 -> null
3 is removed
Why: By linking neighbors directly, node 3 is removed from the list
Result:
null ← 1 ↔ 2 ↔ 4 -> null
Annotated Code
DSA Go
package main

import "fmt"

type Node struct {
	val  int
	prev *Node
	next *Node
}

type DoublyLinkedList struct {
	head *Node
	tail *Node
}

func (dll *DoublyLinkedList) append(val int) {
	newNode := &Node{val: val}
	if dll.head == nil {
		dll.head = newNode
		dll.tail = newNode
		return
	}
	dll.tail.next = newNode
	newNode.prev = dll.tail
	dll.tail = newNode
}

func (dll *DoublyLinkedList) deleteByValue(val int) {
	curr := dll.head
	for curr != nil {
		if curr.val == val {
			if curr.prev != nil {
				curr.prev.next = curr.next // link prev node to next
			} else {
				dll.head = curr.next // deleting head
			}
			if curr.next != nil {
				curr.next.prev = curr.prev // link next node to prev
			} else {
				dll.tail = curr.prev // deleting tail
			}
			return
		}
		curr = curr.next
	}
}

func (dll *DoublyLinkedList) printList() {
	curr := dll.head
	for curr != nil {
		fmt.Printf("%d", curr.val)
		if curr.next != nil {
			fmt.Printf(" ↔ ")
		}
		curr = curr.next
	}
	fmt.Println()
}

func main() {
	dll := &DoublyLinkedList{}
	dll.append(1)
	dll.append(2)
	dll.append(3)
	dll.append(4)

	fmt.Print("Original list: ")
	dll.printList()

	dll.deleteByValue(3)

	fmt.Print("After deleting 3: ")
	dll.printList()
}
for curr != nil {
iterate through nodes to find the value
if curr.val == val {
check if current node has the target value
if curr.prev != nil { curr.prev.next = curr.next } else { dll.head = curr.next }
link previous node's next to current's next or update head if deleting first node
if curr.next != nil { curr.next.prev = curr.prev } else { dll.tail = curr.prev }
link next node's prev to current's prev or update tail if deleting last node
return
stop after deleting the first matching node
OutputSuccess
Original list: 1 ↔ 2 ↔ 3 ↔ 4 After deleting 3: 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 direct access to previous node, making deletion easier without extra traversal
Edge Cases
empty list
no deletion occurs, list remains empty
DSA Go
for curr != nil {
delete head node
head pointer updates to next node
DSA Go
else { dll.head = curr.next }
delete tail node
tail pointer updates to previous node
DSA Go
else { dll.tail = curr.prev }
value not found
list remains unchanged
DSA Go
for curr != nil {
When to Use This Pattern
When you need to remove a node by value in a list where nodes have links both ways, use the delete by value in doubly linked list pattern to efficiently update neighbors.
Common Mistakes
Mistake: Not updating the head or tail pointers when deleting the first or last node
Fix: Add checks to update head if deleting first node and tail if deleting last node
Mistake: Not linking both previous and next nodes correctly, causing broken links
Fix: Always update both prev.next and next.prev pointers when deleting a 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 update both previous and next pointers to bypass the deleted node.

Practice

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

Solution

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

    Traverse the doubly linked list from head to tail to find the node whose data matches the value to delete.
  2. Step 2: Update the 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, effectively removing it from the list.
  3. Final Answer:

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

    Delete by value means remove matching node and fix links [OK]
Hint: Find node by value, then fix previous and next links [OK]
Common Mistakes:
  • Not updating previous node's next pointer
  • Not updating next node's previous pointer
  • Deleting wrong node when multiple have same value
2. Which of the following Go code snippets correctly deletes a node by value from a doubly linked list?
easy
A. if current.data == value { current.next.next = current.prev.prev }
B. if current.data == value { current.next = current.prev; current.prev = current.next }
C. if current.data == value { current = nil }
D. if current.data == value { current.prev.next = current.next; current.next.prev = current.prev }

Solution

  1. Step 1: Check node data against value

    The condition current.data == value correctly identifies the node to delete.
  2. Step 2: Update links correctly

    Setting current.prev.next = current.next and current.next.prev = current.prev properly removes the node by linking its neighbors.
  3. Final Answer:

    if current.data == value { current.prev.next = current.next; current.next.prev = current.prev } -> Option D
  4. Quick Check:

    Correct link updates remove node [OK]
Hint: Update prev.next and next.prev to remove node [OK]
Common Mistakes:
  • Swapping prev and next pointers incorrectly
  • Setting current to nil without fixing links
  • Accessing next or prev without nil checks causing panic
3. Given the doubly linked list: 1 <-> 2 <-> 3 <-> 4 <-> 5, what is the list after deleting the node with value 3?
medium
A. 1 <-> 2 <-> 4 <-> 3 <-> 5
B. 1 <-> 2 <-> 4 <-> 5
C. 2 <-> 3 <-> 4 <-> 5
D. 1 <-> 2 <-> 3 <-> 5

Solution

  1. Step 1: Identify node with value 3

    Traverse the list to find the node containing 3, which is between nodes 2 and 4.
  2. Step 2: Remove node 3 and update links

    Set node 2's next pointer to node 4 and node 4's previous pointer to node 2, skipping node 3.
  3. Final Answer:

    1 <-> 2 <-> 4 <-> 5 -> Option B
  4. Quick Check:

    Node 3 removed, neighbors linked [OK]
Hint: Remove node and link neighbors directly [OK]
Common Mistakes:
  • Leaving node 3 linked causing broken list
  • Deleting wrong node by value
  • Not updating both prev and next pointers
4. Consider this Go code snippet to delete a node by value in a doubly linked list:
func deleteByValue(head *Node, value int) *Node {
    current := head
    for current != nil {
        if current.data == value {
            if current.prev != nil {
                current.prev.next = current.next
            } else {
                head = current.next
            }
            if current.next != nil {
                current.next.prev = current.prev
            }
            break
        }
        current = current.next
    }
    return head
}
What is the bug in this code?
medium
A. It does not handle deleting the last node correctly
B. It does not update head when deleting the first node
C. It breaks after deleting only the first matching node
D. It does not check for nil pointers before accessing prev or next

Solution

  1. Step 1: Analyze loop and break behavior

    The loop breaks immediately after deleting the first node with matching value, so only one node is deleted even if multiple nodes have the same value.
  2. Step 2: Understand implications for multiple matches

    If the list has multiple nodes with the same value, only the first is removed, which may not be the intended behavior if all matches should be deleted.
  3. Final Answer:

    It breaks after deleting only the first matching node -> Option C
  4. Quick Check:

    Break stops after first delete [OK]
Hint: Check if loop breaks too early when deleting multiple nodes [OK]
Common Mistakes:
  • Ignoring multiple nodes with same value
  • Not updating head when first node deleted
  • Not checking nil before pointer access
5. You have a doubly linked list with nodes: 10 <-> 20 <-> 30 <-> 20 <-> 40. You want to delete all nodes with value 20. Which approach correctly deletes all such nodes?
hard
A. Traverse the list and delete nodes with value 20, continuing without breaking the loop
B. Delete the first node with value 20 and then stop traversal
C. Delete nodes with value 20 only if they are at the head or tail
D. Replace nodes with value 20 with a new node containing 0

Solution

  1. Step 1: Traverse entire list without breaking

    To delete all nodes with value 20, you must check every node and not stop after the first deletion.
  2. Step 2: Delete matching nodes and update links carefully

    For each node with value 20, update the previous and next pointers to remove it, then continue traversal to find others.
  3. Final Answer:

    Traverse the list and delete nodes with value 20, continuing without breaking the loop -> Option A
  4. Quick Check:

    Delete all matches by full traversal [OK]
Hint: Do not break loop; delete all matching nodes during traversal [OK]
Common Mistakes:
  • Breaking loop after first deletion
  • Not updating links properly causing broken list
  • Only deleting head or tail nodes
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