Bird
Raised Fist0
DSA Typescriptprogramming

Insert at End of Circular Linked List in DSA Typescript

Choose your learning style10 modes available
Mental Model
A circular linked list connects the last node back to the first, so inserting at the end means adding a new node just before the first node and updating the last node's pointer.
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 everyone still holds hands in a circle.
head -> 1 -> 2 -> 3 -> (back to head 1)
          ↑                   ↓
          ←-------------------
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, keeping the list circular
Step 1: Create new node with value 4
head -> 1 -> 2 -> 3 -> (back to head 1), newNode(4) isolated
Why: We need a new node to insert
Step 2: Find last node (node with value 3) by traversing from head
head -> 1 -> 2 -> [3] -> (back to head 1), newNode(4) isolated
Why: We must link new node after the last node
Step 3: Set last node's next pointer to new node
head -> 1 -> 2 -> 3 -> [4], newNode(4) next is null temporarily
Why: Connect last node to new node
Step 4: Set new node's next pointer to head to maintain circularity
head -> 1 -> 2 -> 3 -> 4 -> (back to head 1)
          ↑                   ↓
          ←-------------------
Why: Keep the list circular by linking new node back to head
Result:
head -> 1 -> 2 -> 3 -> 4 -> (back to head 1)
          ↑                   ↓
          ←-------------------
Annotated Code
DSA Typescript
class Node {
  value: number;
  next: Node | null;
  constructor(value: number) {
    this.value = value;
    this.next = null;
  }
}

class CircularLinkedList {
  head: Node | null = null;

  insertAtEnd(value: number): void {
    const newNode = new Node(value); // create new node
    if (!this.head) {
      this.head = newNode; // empty list, new node is head
      newNode.next = newNode; // points to itself circularly
      return;
    }
    let curr = this.head;
    while (curr.next !== this.head) {
      curr = curr.next!; // advance to last node
    }
    curr.next = newNode; // link last node to new node
    newNode.next = this.head; // new node points back to head
  }

  printList(): void {
    if (!this.head) {
      console.log('List is empty');
      return;
    }
    let curr = this.head;
    let result = '';
    do {
      result += curr.value + ' -> ';
      curr = curr.next!;
    } while (curr !== this.head);
    result += '(back to head ' + this.head.value + ')';
    console.log(result);
  }
}

// Driver code
const cll = new CircularLinkedList();
cll.insertAtEnd(1);
cll.insertAtEnd(2);
cll.insertAtEnd(3);
cll.insertAtEnd(4);
cll.printList();
const newNode = new Node(value); // create new node
create new node to insert
if (!this.head) { this.head = newNode; // empty list, new node is head newNode.next = newNode; // points to itself circularly return; }
handle empty list by making new node point to itself
while (curr.next !== this.head) { curr = curr.next!; // advance to last node }
find last node by traversing until next points to head
curr.next = newNode; // link last node to new node
connect last node to new node
newNode.next = this.head; // new node points back to head
maintain circular link by pointing new node to head
OutputSuccess
1 -> 2 -> 3 -> 4 -> (back to head 1)
Complexity Analysis
Time: O(n) because we traverse the list to find the last node before inserting
Space: O(1) because we only create one new node and use constant extra space
vs Alternative: Compared to a singly linked list without circular links, circular list requires careful pointer update to maintain the loop but insertion time is similar
Edge Cases
empty list
new node becomes head and points to itself
DSA Typescript
if (!this.head) {
  this.head = newNode; // empty list, new node is head
  newNode.next = newNode; // points to itself circularly
  return;
}
single node list
new node inserted after head and points back to head
DSA Typescript
while (curr.next !== this.head) {
  curr = curr.next!; // advance to last node
}
When to Use This Pattern
When you see a linked list where the last node points back to the first, and you need to add a node at the end, use the circular linked list insertion pattern to maintain the loop.
Common Mistakes
Mistake: Not updating the new node's next pointer to head, breaking the circular link
Fix: Always set newNode.next = this.head after linking the last node to newNode
Mistake: Not handling empty list case, causing null pointer errors
Fix: Check if head is null and initialize properly with newNode pointing to itself
Summary
Inserts a new node at the end of a circular linked list while keeping the list circular.
Use when you want to add elements to a circular linked list without breaking its loop structure.
The key is to link the new node after the last node and point it back to the head to maintain circularity.

Practice

(1/5)
1. What happens when you insert a new node at the end of an empty circular linked list?
easy
A. The new node points to null, ending the list.
B. The new node points to itself, becoming the only node in the list.
C. The list remains empty because insertion is not possible.
D. The new node points to the head, but the list has multiple nodes.

Solution

  1. Step 1: Understand empty circular linked list

    An empty circular linked list has no nodes, so inserting the first node means it must point to itself to maintain circularity.
  2. Step 2: Insert new node and set its next pointer

    The new node's next pointer is set to itself, making it the only node and the head of the list.
  3. Final Answer:

    The new node points to itself, becoming the only node in the list. -> Option B
  4. Quick Check:

    Empty list insertion = node points to itself [OK]
Hint: First node in circular list points to itself [OK]
Common Mistakes:
  • Setting next pointer to null instead of itself
  • Assuming list remains empty after insertion
  • Not updating head pointer to new node
2. Which of the following TypeScript code snippets correctly inserts a new node at the end of a circular linked list?
easy
A. newNode.next = head; head.next = newNode; tail = newNode;
B. newNode.next = null; tail.next = newNode; tail = newNode;
C. newNode.next = head; tail.next = newNode; tail = newNode;
D. newNode.next = tail; head.next = newNode; tail = newNode;

Solution

  1. Step 1: Set new node's next to head

    In a circular linked list, the last node points to the head, so newNode.next must point to head.
  2. Step 2: Update tail's next and tail pointer

    Tail's next is updated to newNode, and tail pointer moves to newNode to mark new end.
  3. Final Answer:

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

    New node points to head, tail updated [OK]
Hint: New node's next always points to head in circular list [OK]
Common Mistakes:
  • Setting newNode.next to null breaks circularity
  • Updating head.next instead of tail.next
  • Not moving tail pointer to new node
3. Given the circular linked list: 10 -> 20 -> 30 -> (back to 10), what is the list after inserting 40 at the end?
medium
A. 10 -> 20 -> 30 -> 40 -> 10
B. 40 -> 10 -> 20 -> 30 -> 40
C. 10 -> 20 -> 30 -> 40 -> null
D. 10 -> 20 -> 30 -> 10 -> 40

Solution

  1. Step 1: Understand circular list structure

    Original list loops from 30 back to 10, so last node 30 points to head 10.
  2. Step 2: Insert 40 at end and update pointers

    New node 40 points to head 10, old tail 30 points to 40, maintaining circularity.
  3. Final Answer:

    10 -> 20 -> 30 -> 40 -> 10 -> Option A
  4. Quick Check:

    New node added before head, tail points to new node [OK]
Hint: New tail points to head, list stays circular [OK]
Common Mistakes:
  • Adding null at end breaks circularity
  • Inserting new node at head instead of tail
  • Incorrect pointer updates causing loops
4. Identify the error in this TypeScript code snippet for inserting at the end of a circular linked list:
function insertEnd(tail: Node | null, data: number): Node {
  const newNode = new Node(data);
  if (!tail) {
    newNode.next = null;
    return newNode;
  }
  newNode.next = tail.next;
  tail.next = newNode;
  return newNode;
}
medium
A. newNode.next should point to itself when list is empty
B. Returning newNode instead of tail breaks list reference
C. newNode.next should point to tail.next, not null when list is empty
D. tail.next should not be updated in insertion

Solution

  1. Step 1: Check empty list insertion

    When tail is null (empty list), newNode.next should point to itself to maintain circularity, not null.
  2. Step 2: Verify pointer updates for non-empty list

    For non-empty list, newNode.next = tail.next (head), tail.next = newNode is correct.
  3. Final Answer:

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

    Empty list node points to itself [OK]
Hint: Empty circular list node points to itself, not null [OK]
Common Mistakes:
  • Setting newNode.next to null breaks circularity
  • Returning newNode instead of updating tail reference
  • Not updating tail.next pointer
5. You have a circular linked list with nodes 5 -> 15 -> 25 -> (back to 5). You want to insert 35 at the end and then insert 2 at the beginning. What is the correct final circular linked list?
hard
A. 35 -> 2 -> 5 -> 15 -> 25 -> 35
B. 5 -> 15 -> 25 -> 35 -> 2 -> 5
C. 2 -> 5 -> 15 -> 25 -> 35 -> 5
D. 2 -> 5 -> 15 -> 25 -> 35 -> 2

Solution

  1. Step 1: Insert 35 at end

    After inserting 35, list is 5 -> 15 -> 25 -> 35 -> back to 5.
  2. Step 2: Insert 2 at beginning

    Insert at beginning means new node 2 points to current head 5, tail's next updated to 2, making 2 the new head.
  3. Step 3: Final circular list

    The list is 2 -> 5 -> 15 -> 25 -> 35 -> back to 2, maintaining circularity.
  4. Final Answer:

    2 -> 5 -> 15 -> 25 -> 35 -> 2 -> Option D
  5. Quick Check:

    New head inserted, tail points to new head [OK]
Hint: Tail's next always points to head in circular list [OK]
Common Mistakes:
  • Not updating tail.next after inserting at beginning
  • Inserting new node at end but not updating tail
  • Breaking circular link by pointing to wrong node
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