0
0
DSA Pythonprogramming~10 mins

Insert at End of Circular Linked List in DSA Python - Execution Trace

Choose your learning style9 modes available
Concept Flow - Insert at End of Circular Linked List
Create new node
↓
Is list empty?
Yes→new_node.next = new_node, head = new_node
No↓
Start at head
↓
Traverse to last node (node.next != head)?
Yes↓
Move to next node
Back to traverse↓
last_node.next = new_node
↓
new_node.next = head
↓
Update tail pointer if used
↓
Done
↩Back to traverse
Insert a new node at the end by linking it after the last node, which points back to head, maintaining circularity.
Execution Sample
DSA Python
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def insert_at_end(head, data):
    new_node = Node(data)
    if head is None:
        new_node.next = new_node
        return new_node
    current = head
    while current.next != head:
        current = current.next
    current.next = new_node
    new_node.next = head
    return head

# Example (initial list: 10->20->30->10)
# head = insert_at_end(head, 40)  # Results in 10->20->30->40->10
Complete function to insert at the end of a circular singly linked list. Handles empty list. Traverses to last node (where next == head), links new node, sets its next to head.
Execution Table
StepOperationNodes in ListPointer ChangesVisual State
1Create new node with data=4010 -> 20 -> 30 (circular)new_node.next = Noneā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ next:──┼──→ │ next:──┼──→ │ next:──┼──→ head ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head
2Check if list is empty10 -> 20 -> 30 (circular)No changeSame as step 1
3Start traversal at head (node=10)10 -> 20 -> 30 (circular)current = head (10)Same as step 1
4Check if current.next != head (20 != 10)10 -> 20 -> 30 (circular)No changeSame as step 1
5Move current to next node (20)10 -> 20 -> 30 (circular)current = 20Same as step 1
6Check if current.next != head (30 != 10)10 -> 20 -> 30 (circular)No changeSame as step 1
7Move current to next node (30)10 -> 20 -> 30 (circular)current = 30Same as step 1
8Check if current.next != head (10 == 10)10 -> 20 -> 30 (circular)No changeSame as step 1
9Set current.next = new_node (30.next = 40)10 -> 20 -> 30 -> 40 (circular)30.next → 40ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ data:40│ │ next:──┼──→ │ next:──┼──→ │ next:──┼──→ │ next:āˆ… │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head
10Set new_node.next = head (40.next = 10)10 -> 20 -> 30 -> 40 (circular)40.next → 10ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ data:40│ │ next:──┼──→ │ next:──┼──→ │ next:──┼──→ │ next:──┼──→ head ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head
11Insertion complete10 -> 20 -> 30 -> 40 (circular)List circular and updatedFinal circular list with new node at end
šŸ’” Traversal stops when current.next == head, then new node inserted after current.
Variable Tracker
VariableStartAfter Step 3After Step 5After Step 7After Step 9After Step 10Final
headNode(10)Node(10)Node(10)Node(10)Node(10)Node(10)Node(10)
currentNoneNode(10)Node(20)Node(30)Node(30)Node(30)Node(30)
new_nodeNoneNode(40)Node(40)Node(40)Node(40)Node(40)Node(40)
new_node.nextNoneNoneNoneNoneNoneNode(10)Node(10)
current.nextNode(20)Node(20)Node(30)Node(10)Node(40)Node(40)Node(40)
Key Moments - 3 Insights
Why do we check if current.next == head to stop traversal?
Because in a circular linked list, the last node points back to head. When current.next == head, we reached the last node. See execution_table step 8.
What happens if the list is empty when inserting?
If empty, new_node.next points to itself and head is set to new_node, making a single-node circular list. This is shown in concept_flow under 'Is list empty?'.
Why do we set new_node.next = head after insertion?
To maintain circularity, the new last node must point back to head. See execution_table step 10 for this pointer update.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'current' after step 5?
ANode with data 20
BNode with data 10
CNode with data 30
DNone
šŸ’” Hint
Check the 'current' variable column in variable_tracker after step 5.
At which step does the new node's next pointer get assigned to head?
AStep 7
BStep 9
CStep 10
DStep 11
šŸ’” Hint
Look at the 'Pointer Changes' column in execution_table for step 10.
If the list was empty, which operation would happen first?
ATraverse to last node
BSet new_node.next = new_node and head = new_node
CSet current.next = new_node
DMove current to next node
šŸ’” Hint
Refer to concept_flow decision for empty list case.
Concept Snapshot
Insert at End of Circular Linked List:
- Create new node
- If list empty: new_node.next = new_node, head = new_node
- Else traverse to last node (node.next == head)
- Set last_node.next = new_node
- Set new_node.next = head
- List remains circular with new node at end
Full Transcript
To insert at the end of a circular linked list, first create a new node. If the list is empty, point the new node's next to itself and set head to this node, forming a single-node circle. If not empty, start at head and traverse nodes until you find the last node, identified when its next points back to head. Then, link the last node's next to the new node, and set the new node's next to head to maintain circularity. This process ensures the list remains circular with the new node at the end.