Bird
Raised Fist0
DSA Goprogramming

Delete a Node from Circular Linked List in DSA Go

Choose your learning style10 modes available
Mental Model
A circular linked list loops back to the start, so deleting a node means reconnecting neighbors without breaking the circle.
Analogy: Imagine people sitting in a circle holding hands. Removing one person means their neighbors hold hands directly, keeping the circle unbroken.
head -> 1 -> 2 -> 3 -> 4 -> back to head (1)
          ↑                        ↓
          ←-----------------------
Dry Run Walkthrough
Input: list: 1 -> 2 -> 3 -> 4 -> back to 1, delete node with value 3
Goal: Remove node 3 and keep the list circular without breaking the loop
Step 1: start at head node 1, look for node with value 3
1 -> [curr->2] -> 3 -> 4 -> back to 1
Why: We need to find the node before the one to delete to reconnect pointers
Step 2: advance curr to node 2, check next node value
1 -> 2 -> [curr->3] -> 4 -> back to 1
Why: Check if next node is the one to delete
Step 3: found node 3 to delete, set curr.next to node 4, skipping node 3
1 -> 2 -> 4 -> back to 1
Why: By skipping node 3, we remove it and keep the circle intact
Result:
1 -> 2 -> 4 -> back to 1
Annotated Code
DSA Go
package main

import "fmt"

type Node struct {
	val  int
	next *Node
}

// deleteNode deletes the node with given value from circular linked list
func deleteNode(head *Node, key int) *Node {
	if head == nil {
		return nil // empty list
	}

	curr := head
	prev := head

	// if list has only one node
	if head.next == head {
		if head.val == key {
			return nil // list becomes empty
		} else {
			return head
		}
	}

	// find the node to delete
	for {
		if curr.val == key {
			break
		}
		prev = curr
		curr = curr.next
		if curr == head {
			return head // key not found
		}
	}

	// if node to delete is head
	if curr == head {
		newHead := head.next
		last := head
		for last.next != head {
			last = last.next
		}
		last.next = newHead
		return newHead
	}

	// remove curr by linking prev to curr.next
	prev.next = curr.next

	return head
}

func printList(head *Node) {
	if head == nil {
		fmt.Println("empty list")
		return
	}
	curr := head
	for {
		fmt.Printf("%d -> ", curr.val)
		curr = curr.next
		if curr == head {
			break
		}
	}
	fmt.Println("back to head")
}

func main() {
	// create circular list 1->2->3->4->back to 1
	n1 := &Node{val: 1}
	n2 := &Node{val: 2}
	n3 := &Node{val: 3}
	n4 := &Node{val: 4}
	n1.next = n2
	n2.next = n3
	n3.next = n4
	n4.next = n1

	fmt.Println("Original list:")
	printList(n1)

	head := deleteNode(n1, 3)

	fmt.Println("After deleting 3:")
	printList(head)
}
if head == nil { return nil }
handle empty list case
if head.next == head { if head.val == key { return nil } else { return head } }
handle single node list deletion
for { if curr.val == key { break } prev = curr; curr = curr.next; if curr == head { return head } }
search for node with key, stop if full circle done
if curr == head { newHead := head.next; last := head; for last.next != head { last = last.next }; last.next = newHead; return newHead }
if deleting head, find last node, link to newHead and return it
prev.next = curr.next
unlink node to delete by skipping it
OutputSuccess
Original list: 1 -> 2 -> 3 -> 4 -> back to head After deleting 3: 1 -> 2 -> 4 -> back to head
Complexity Analysis
Time: O(n) because in worst case we traverse all nodes once to find the node to delete
Space: O(1) because we only use a few pointers regardless of list size
vs Alternative: Compared to singly linked list deletion, circular list requires careful handling of the loop but has similar time complexity
Edge Cases
empty list
function returns nil immediately without error
DSA Go
if head == nil { return nil }
single node list where node matches key
list becomes empty (nil) after deletion
DSA Go
if head.next == head { if head.val == key { return nil } }
key not found in list
list remains unchanged and head is returned
DSA Go
if curr == head { return head }
When to Use This Pattern
When you see a problem asking to delete a node in a circular linked list, use the pattern of searching for the node and reconnecting neighbors carefully to keep the circle unbroken.
Common Mistakes
Mistake: Not updating the head pointer when the node to delete is the head
Fix: Find the last node, set last.next = head.next, then return head.next
Mistake: Not handling the single node list case, causing infinite loops or errors
Fix: Check if head.next == head and handle deletion accordingly
Mistake: Looping infinitely if key is not found
Fix: Stop search when curr returns to head and return original list
Summary
Deletes a node with a given value from a circular linked list while keeping the list circular.
Use when you need to remove elements from a circular linked list without breaking its loop structure.
The key is to find the node before the one to delete and reconnect its next pointer to skip the deleted node.

Practice

(1/5)
1. What happens when you delete the only node in a circular linked list?
easy
A. The list still contains the deleted node.
B. The list becomes empty (head points to nil).
C. The list forms a linear linked list.
D. The list throws an error automatically.

Solution

  1. Step 1: Understand single-node circular list

    A circular linked list with one node points to itself.
  2. Step 2: Delete the only node

    Removing this node means no nodes remain, so head becomes nil.
  3. Final Answer:

    The list becomes empty (head points to nil). -> Option B
  4. Quick Check:

    Single node deleted = empty list [OK]
Hint: Deleting last node empties the list, head = nil [OK]
Common Mistakes:
  • Assuming list still has nodes after deleting the only node
  • Not updating head to nil
  • Confusing circular with linear list after deletion
2. Which Go syntax correctly moves the head pointer when deleting the head node from a circular linked list?
easy
A. head.next = head
B. head = nil.next
C. head = head.next
D. head = head.prev

Solution

  1. Step 1: Identify head deletion logic

    Deleting head means moving head pointer to next node.
  2. Step 2: Check syntax correctness

    Assigning head = head.next correctly moves head to next node.
  3. Final Answer:

    head = head.next -> Option C
  4. Quick Check:

    Move head to next node = head = head.next [OK]
Hint: Move head pointer to next node to delete head [OK]
Common Mistakes:
  • Using nil.next causes runtime error
  • Assigning head.next = head does not delete node
  • Using head.prev is invalid for singly circular list
3. Given this circular linked list: 1 -> 2 -> 3 -> (back to 1), what is the list after deleting node with value 2?
medium
A. 1 -> 3 -> (back to 1)
B. 1 -> 2 -> 3 -> (back to 1)
C. 2 -> 3 -> (back to 2)
D. 3 -> 1 -> (back to 3)

Solution

  1. Step 1: Locate node with value 2

    Node 2 is between nodes 1 and 3 in the circular list.
  2. Step 2: Remove node 2 by linking 1 to 3

    Update node 1's next pointer to node 3, skipping node 2.
  3. Final Answer:

    1 -> 3 -> (back to 1) -> Option A
  4. Quick Check:

    Deleted 2, linked 1 to 3 [OK]
Hint: Link previous node to next of deleted node [OK]
Common Mistakes:
  • Not updating previous node's next pointer
  • Deleting wrong node
  • Breaking circular link
4. What is wrong with this Go code snippet for deleting a node from a circular linked list?
func deleteNode(head *Node, key int) *Node {
  if head == nil {
    return nil
  }
  curr := head
  for curr.next != head && curr.next.data != key {
    curr = curr.next
  }
  if curr.next.data == key {
    curr.next = curr.next.next
  }
  return head
}
medium
A. It returns nil always.
B. It causes infinite loop always.
C. It deletes all nodes with the key.
D. It does not handle deleting the head node correctly.

Solution

  1. Step 1: Analyze deletion logic

    The code searches for node before target and skips target node.
  2. Step 2: Check head deletion case

    If the node to delete is head, head pointer is not updated, causing incorrect list.
  3. Final Answer:

    It does not handle deleting the head node correctly. -> Option D
  4. Quick Check:

    Head deletion needs head pointer update [OK]
Hint: Update head if deleting head node [OK]
Common Mistakes:
  • Ignoring head node deletion
  • Not updating head pointer
  • Assuming key always exists
5. You have a circular linked list: 10 -> 20 -> 30 -> 40 -> (back to 10). You want to delete node with value 10 (head). Which steps correctly update the list?
hard
A. Find last node (40), set its next to head.next (20), then update head to 20.
B. Set head to nil directly without updating last node.
C. Delete node 10 by setting head.next to nil.
D. Swap data of head and next node, then delete next node.

Solution

  1. Step 1: Find last node pointing to head

    Traverse list to find node 40 which points to head (10).
  2. Step 2: Update last node's next pointer

    Set node 40's next to head.next (node 20) to maintain circularity.
  3. Step 3: Update head pointer

    Set head to head.next (node 20) to delete original head.
  4. Final Answer:

    Find last node (40), set its next to head.next (20), then update head to 20. -> Option A
  5. Quick Check:

    Update last node and head to delete head node [OK]
Hint: Update last node's next and head to delete head [OK]
Common Mistakes:
  • Not updating last node's next pointer
  • Setting head to nil breaks list
  • Deleting node by setting next to nil
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