Bird
Raised Fist0
DSA Pythonprogramming

Insert at End of Circular Linked List in DSA Python

Choose your learning style10 modes available
Mental Model
A circular linked list connects the last node back to the first, forming a loop. Inserting at the end means adding a new node just before the first node and updating the last node to point to this new node.
Analogy: Imagine people sitting in a circle holding hands. Adding a new person at the end means placing them just before the first person and making sure the last person now holds the new person's hand, keeping the circle unbroken.
head -> 1 -> 2 -> 3 -> back to head (1)

Visual: 1 -> 2 -> 3 ->
          ↑         ↓
          ←---------
Dry Run Walkthrough
Input: list: 1 -> 2 -> 3 (circular), insert value 4 at end
Goal: Add a new node with value 4 at the end, maintaining the circular link
Step 1: Create new node with value 4
1 -> 2 -> 3 -> back to 1, new node 4 (isolated)
Why: We need a new node to insert at the end
Step 2: Find last node (node with value 3) by traversing from head
1 -> 2 -> [3] -> back to 1, new node 4 (isolated)
Why: To insert at end, we must find the current last node
Step 3: Set last node's next pointer from 1 to new node 4
1 -> 2 -> 3 -> 4 (new), 4 -> back to 1
Why: Link last node to new node to add it at the end
Step 4: Set new node 4's next pointer to head (node 1)
1 -> 2 -> 3 -> 4 -> back to 1

Visual loop maintained
Why: Maintain circular link by pointing new node back to head
Result:
1 -> 2 -> 3 -> 4 -> back to 1
Annotated Code
DSA Python
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

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

    def insert_at_end(self, data):
        new_node = Node(data)  # create new node
        if not self.head:
            new_node.next = new_node  # points to itself
            self.head = new_node
            return
        curr = self.head
        while curr.next != self.head:  # find last node
            curr = curr.next
        curr.next = new_node  # last node points to new node
        new_node.next = self.head  # new node points to head

    def __str__(self):
        if not self.head:
            return "empty"
        result = []
        curr = self.head
        while True:
            result.append(str(curr.data))
            curr = curr.next
            if curr == self.head:
                break
        return " -> ".join(result) + " -> back to " + str(self.head.data)

# Driver code
cll = CircularLinkedList()
cll.insert_at_end(1)
cll.insert_at_end(2)
cll.insert_at_end(3)
cll.insert_at_end(4)
print(cll)
new_node = Node(data) # create new node
create the new node to insert
if not self.head: new_node.next = new_node # points to itself self.head = new_node return
handle empty list by pointing new node to itself and setting head
while curr.next != self.head: # find last node curr = curr.next
traverse to find the last node which points back to head
curr.next = new_node # last node points to new node
link last node to new node to insert at end
new_node.next = self.head # new node points to head
maintain circular link by pointing new node back to head
OutputSuccess
1 -> 2 -> 3 -> 4 -> back to 1
Complexity Analysis
Time: O(n) because we traverse the list to find the last node before insertion
Space: O(1) because we only create one new node and use a few pointers
vs Alternative: Compared to a singly linked list, circular linked list requires careful pointer updates to maintain the loop, but insertion at end is similar in time cost
Edge Cases
empty list
new node points to itself and becomes head, forming a single-node circular list
DSA Python
if not self.head:
    new_node.next = new_node  # points to itself
    self.head = new_node
    return
single node list
new node inserted after the single node, and circular link maintained
DSA Python
while curr.next != self.head:  # find last node
    curr = curr.next
When to Use This Pattern
When you see a problem requiring insertion at the end of a circular linked list, look for traversal to the last node and pointer updates that maintain the loop.
Common Mistakes
Mistake: Not updating the new node's next pointer to head, breaking the circular link
Fix: Always set new_node.next = self.head after insertion
Mistake: Not handling empty list case, causing errors when head is None
Fix: Check if head is None and initialize the list properly by pointing new node to itself
Summary
Adds a new node at the end of a circular linked list while keeping the loop intact.
Use when you need to append data to a circular linked list without breaking its circular nature.
The key is to find the last node and update pointers so the new node points back to the head.

Practice

(1/5)
1. What happens when you insert a new node at the end of a circular linked list that currently has nodes?
easy
A. The new node is ignored because the list is circular.
B. The new node becomes the head node and points to itself only.
C. The new node is inserted at the beginning and breaks the circular link.
D. The new node becomes the last node and points back to the head node.

Solution

  1. Step 1: Understand the circular linked list structure

    In a circular linked list, the last node points back to the head node, forming a circle.
  2. Step 2: Insert new node at the end

    The new node is linked after the current last node, and its next pointer is set to the head node, maintaining the circle.
  3. Final Answer:

    The new node becomes the last node and points back to the head node. -> Option D
  4. Quick Check:

    Insert at end keeps circle intact = D [OK]
Hint: New end node always points to head to keep circle [OK]
Common Mistakes:
  • Forgetting to link new node back to head
  • Breaking the circular link by pointing to None
  • Inserting at beginning instead of end
2. Which of the following is the correct syntax to create a new node and insert it at the end of a circular linked list in Python?
easy
A. new_node = Node(data); new_node.next = None; last.next = new_node
B. new_node = Node(data); new_node.next = head; last.next = new_node
C. new_node = Node(data); head = new_node; new_node.next = head
D. new_node = Node(data); last.next = None; new_node.next = last

Solution

  1. Step 1: Create new node and link to head

    The new node's next pointer must point to the head to maintain circularity.
  2. Step 2: Link last node to new node

    The current last node's next pointer is updated to point to the new node, completing the insertion.
  3. Final Answer:

    new_node = Node(data); new_node.next = head; last.next = new_node -> Option B
  4. Quick Check:

    New node points to head, last points to new node = A [OK]
Hint: New node next = head; last next = new node [OK]
Common Mistakes:
  • Setting new node next to None breaks circularity
  • Not updating last node's next pointer
  • Assigning head to new node incorrectly
3. What will be the printed output of the circular linked list after inserting 4 at the end, given the initial list is 1 -> 2 -> 3 -> (back to 1)?
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def insert_end(head, data):
    new_node = Node(data)
    if not head:
        new_node.next = new_node
        return new_node
    temp = head
    while temp.next != head:
        temp = temp.next
    temp.next = new_node
    new_node.next = head
    return head

head = Node(1)
second = Node(2)
third = Node(3)
head.next = second
second.next = third
third.next = head

head = insert_end(head, 4)

# Print circular list
current = head
output = []
while True:
    output.append(current.data)
    current = current.next
    if current == head:
        break
print(output)
medium
A. [1, 2, 3]
B. [4, 1, 2, 3]
C. [1, 2, 3, 4]
D. [1, 2, 3, 4, 1]

Solution

  1. Step 1: Insert 4 at the end of the circular list

    The function finds the last node (3), links it to new node (4), and new node points back to head (1).
  2. Step 2: Print nodes starting from head

    Traverse from head: 1 -> 2 -> 3 -> 4, then back to 1 stops loop. Output list is [1, 2, 3, 4].
  3. Final Answer:

    [1, 2, 3, 4] -> Option C
  4. Quick Check:

    List after insert = [1, 2, 3, 4] [OK]
Hint: Traverse until back to head to print full circular list [OK]
Common Mistakes:
  • Printing extra repeated head node
  • Not updating last node's next pointer
  • Stopping traversal too early
4. Identify the error in this code snippet for inserting at the end of a circular linked list:
def insert_end(head, data):
    new_node = Node(data)
    if not head:
        new_node.next = None
        return new_node
    temp = head
    while temp.next != head:
        temp = temp.next
    temp.next = new_node
    new_node.next = head
    return head
medium
A. new_node.next should point to new_node when list is empty
B. temp.next should be set to None instead of new_node
C. The while loop condition should be temp.next == head
D. The function should return new_node instead of head

Solution

  1. Step 1: Check empty list case

    When list is empty, new_node.next must point to itself to form a circular list, not None.
  2. Step 2: Verify rest of code

    Other parts correctly insert new_node at end and maintain circularity.
  3. Final Answer:

    new_node.next should point to new_node when list is empty -> Option A
  4. Quick Check:

    Empty list node points to itself = B [OK]
Hint: Empty circular list node points to itself, not None [OK]
Common Mistakes:
  • Setting new_node.next to None breaks circularity
  • Wrong while loop condition
  • Returning wrong node after insertion
5. Given a circular linked list with nodes 10 -> 20 -> 30 -> (back to 10), write the output after inserting 5 at the end and then inserting 40 at the end. What is the final list printed?
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def insert_end(head, data):
    new_node = Node(data)
    if not head:
        new_node.next = new_node
        return new_node
    temp = head
    while temp.next != head:
        temp = temp.next
    temp.next = new_node
    new_node.next = head
    return head

head = Node(10)
second = Node(20)
third = Node(30)
head.next = second
second.next = third
third.next = head

head = insert_end(head, 5)
head = insert_end(head, 40)

current = head
output = []
while True:
    output.append(current.data)
    current = current.next
    if current == head:
        break
print(output)
hard
A. [10, 20, 30, 5, 40]
B. [5, 10, 20, 30, 40]
C. [10, 20, 30, 40, 5]
D. [40, 10, 20, 30, 5]

Solution

  1. Step 1: Insert 5 at the end

    After first insertion, list becomes 10 -> 20 -> 30 -> 5 -> (back to 10).
  2. Step 2: Insert 40 at the end

    After second insertion, list becomes 10 -> 20 -> 30 -> 5 -> 40 -> (back to 10).
  3. Step 3: Print the list

    Traverse from head: 10, 20, 30, 5, 40, then back to 10 stops loop. Output is [10, 20, 30, 5, 40].
  4. Final Answer:

    [10, 20, 30, 5, 40] -> Option A
  5. Quick Check:

    Two inserts at end add nodes in order = A [OK]
Hint: Insertions add nodes at end, order preserved [OK]
Common Mistakes:
  • Inserting new nodes at beginning by mistake
  • Not updating last node's next pointer correctly
  • Printing extra repeated 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