Bird
Raised Fist0
DSA Javascriptprogramming

Create a Circular Singly Linked List in DSA Javascript

Choose your learning style10 modes available
Mental Model
A circular singly linked list is like a chain where the last link connects back to the first, making a loop.
Analogy: Imagine a round table where each person holds hands with the next, and the last person holds hands with the first, so everyone forms a circle.
head -> 1 -> 2 -> 3 ->
↑                   ↓
←←←←←←←←←←←←←←←←←←←←←
Dry Run Walkthrough
Input: Create circular list with values 1, 2, 3
Goal: Build a circular singly linked list where last node points back to head
Step 1: Create node with value 1 and set it as head
head -> [1] -> head
Why: Start the list with the first node and link it to itself to form a circle
Step 2: Create node with value 2 and link it after node 1
head -> 1 -> [2] -> head
Why: Add second node to the list
Step 3: Create node with value 3 and link it after node 2
head -> 1 -> 2 -> [3] -> head
Why: Add third node to the list
Step 4: Link last node (3) back to head (1) to form a circle
head -> 1 -> 2 -> 3 -> [head]
Why: Make the list circular by connecting last node to first
Result:
head -> 1 -> 2 -> 3 -> head (circle formed)
Annotated Code
DSA Javascript
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class CircularSinglyLinkedList {
  constructor() {
    this.head = null;
  }

  append(value) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
      newNode.next = this.head; // link to itself to form circle
      return;
    }
    let current = this.head;
    while (current.next !== this.head) {
      current = current.next; // advance to last node
    }
    current.next = newNode; // link last node to new node
    newNode.next = this.head; // link new node back to head
  }

  printList() {
    if (!this.head) {
      console.log('List is empty');
      return;
    }
    let current = this.head;
    let result = '';
    do {
      result += current.value + ' -> ';
      current = current.next; // move to next node
    } while (current !== this.head);
    result += '(head)';
    console.log(result);
  }
}

// Driver code
const list = new CircularSinglyLinkedList();
list.append(1);
list.append(2);
list.append(3);
list.printList();
newNode.next = this.head; // link to itself to form circle
link first node to itself to start circular list
while (current.next !== this.head) { current = current.next; // advance to last node }
find last node by checking next pointer against head
current.next = newNode; // link last node to new node
append new node after last node
newNode.next = this.head; // link new node back to head
close the circle by linking new node back to head
do { result += current.value + ' -> '; current = current.next; // move to next node } while (current !== this.head);
traverse circular list until back to head to print all nodes
OutputSuccess
1 -> 2 -> 3 -> (head)
Complexity Analysis
Time: O(n) because appending requires traversing all nodes to find the last one
Space: O(n) because each new node uses extra memory proportional to number of nodes
vs Alternative: Compared to singly linked list without circle, circular list requires extra step to link last node back to head, but traversal can loop infinitely if not careful
Edge Cases
empty list
append creates first node and links it to itself
DSA Javascript
if (!this.head) {
  this.head = newNode;
  newNode.next = this.head; // link to itself to form circle
  return;
}
single node list
new nodes append after the single node and circle is maintained
DSA Javascript
while (current.next !== this.head) {
  current = current.next; // advance to last node
}
When to Use This Pattern
When you see a problem requiring a list where you can loop back to the start easily, think of circular singly linked list to avoid null ends and enable continuous traversal.
Common Mistakes
Mistake: Not linking the last node back to the head, leaving the list linear
Fix: Always set last node's next pointer to head after appending new nodes
Mistake: Infinite loop when printing because stopping condition is missing
Fix: Use a do-while loop and stop when current node equals head again
Summary
Creates a linked list where the last node points back to the first, forming a circle.
Use when you want to cycle through elements repeatedly without null ends.
The key is linking the last node's next pointer back to the head node.

Practice

(1/5)
1. What is a key characteristic of a circular singly linked list compared to a regular singly linked list?
easy
A. The last node points back to the first node, forming a circle.
B. Each node has two pointers, one to the next and one to the previous node.
C. It stores data in a sorted order automatically.
D. It uses an array internally to store nodes.

Solution

  1. Step 1: Understand the structure of a circular singly linked list

    In a circular singly linked list, the last node's next pointer points back to the first node, creating a loop.
  2. Step 2: Compare with other linked lists

    Unlike doubly linked lists, circular singly linked lists have only one pointer per node and form a circle, not a linear chain.
  3. Final Answer:

    The last node points back to the first node, forming a circle. -> Option A
  4. Quick Check:

    Last node's next = first node [OK]
Hint: Remember: circular means last node links to first [OK]
Common Mistakes:
  • Confusing circular singly linked list with doubly linked list
  • Thinking nodes have two pointers
  • Assuming data is sorted automatically
2. Which of the following is the correct way to initialize an empty circular singly linked list in JavaScript?
easy
A. const head = { data: null, next: head };
B. const head = null; // no nodes yet
C. const head = { data: null, next: null };
D. const head = []; // empty array

Solution

  1. Step 1: Understand empty list initialization

    An empty circular singly linked list has no nodes, so the head pointer is null.
  2. Step 2: Check other options

    const head = { data: null, next: null }; creates a node with null data and next pointer, which is not empty. const head = { data: null, next: head }; references head before assignment, causing error. const head = []; // empty array uses an array, not a linked list.
  3. Final Answer:

    const head = null; // no nodes yet -> Option B
  4. Quick Check:

    Empty list head = null [OK]
Hint: Empty list means head is null, no nodes created [OK]
Common Mistakes:
  • Creating a node with null data instead of null head
  • Referencing head before declaration
  • Using arrays instead of linked list nodes
3. What will be the output of the following code snippet that creates a circular singly linked list with nodes 1, 2, 3 and prints the list once?
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class CircularSinglyLinkedList {
  constructor() {
    this.head = null;
  }

  append(data) {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
      newNode.next = this.head;
    } else {
      let temp = this.head;
      while (temp.next !== this.head) {
        temp = temp.next;
      }
      temp.next = newNode;
      newNode.next = this.head;
    }
  }

  printList() {
    if (!this.head) return '';
    let result = '';
    let temp = this.head;
    do {
      result += temp.data + ' -> ';
      temp = temp.next;
    } while (temp !== this.head);
    result += 'null';
    return result;
  }
}

const list = new CircularSinglyLinkedList();
list.append(1);
list.append(2);
list.append(3);
console.log(list.printList());
medium
A. null
B. 1 -> 2 -> 3 -> 1 -> 2 -> 3 -> null
C. 1 -> 2 -> 3
D. 1 -> 2 -> 3 -> null

Solution

  1. Step 1: Understand append method behavior

    Each new node is added at the end, and its next points to head, maintaining circularity.
  2. Step 2: Trace printList method

    printList starts at head and loops until it reaches head again, appending data with ' -> '. Finally adds 'null'. So output is '1 -> 2 -> 3 -> null'.
  3. Final Answer:

    1 -> 2 -> 3 -> null -> Option D
  4. Quick Check:

    Print once around circle = 1 -> 2 -> 3 -> null [OK]
Hint: Print loops until back to head once, then stops [OK]
Common Mistakes:
  • Printing infinite loop by not stopping at head
  • Missing 'null' at end
  • Printing nodes multiple times
4. Identify the bug in this code snippet that tries to append a node to a circular singly linked list:
append(data) {
  const newNode = new Node(data);
  if (!this.head) {
    this.head = newNode;
    newNode.next = null;
  } else {
    let temp = this.head;
    while (temp.next !== this.head) {
      temp = temp.next;
    }
    temp.next = newNode;
    newNode.next = this.head;
  }
}
medium
A. newNode.next should point to this.head when list is empty, not null.
B. The while loop condition should be temp.next === this.head.
C. The head should be set to newNode every time a node is appended.
D. The newNode should not be created inside the append method.

Solution

  1. Step 1: Check initialization for empty list

    When list is empty, newNode.next must point to head itself to maintain circularity, not null.
  2. Step 2: Verify loop and pointer updates

    The while loop and pointer updates are correct; only the initial next pointer is wrong.
  3. Final Answer:

    newNode.next should point to this.head when list is empty, not null. -> Option A
  4. Quick Check:

    Empty list node next = head, not null [OK]
Hint: Empty list node next must loop to itself [OK]
Common Mistakes:
  • Setting newNode.next to null breaks circular link
  • Wrong while loop condition
  • Resetting head incorrectly
5. You want to insert a new node with value 4 after the node with value 3 in a circular singly linked list. Given the list: 3 -> 1 -> 2 -> (back to 3), which code snippet correctly performs this insertion?
hard
A. let temp = head; while (temp.next !== head) { temp = temp.next; } const newNode = new Node(4); temp.next = newNode; newNode.next = head;
B. const newNode = new Node(4); newNode.next = head; head.next = newNode;
C. let temp = head; while (temp.data !== 3) { temp = temp.next; } const newNode = new Node(4); newNode.next = temp.next; temp.next = newNode;
D. head = new Node(4); head.next = oldHead;

Solution

  1. Step 1: Locate node with value 3

    Traverse from head until temp.data equals 3 to find the correct insertion point.
  2. Step 2: Insert new node after node 3

    Create newNode with data 4, set newNode.next to temp.next, then set temp.next to newNode to insert correctly.
  3. Final Answer:

    Traverse from head until finding node with value 3, then insert new node after it. -> Option C
  4. Quick Check:

    Insert after node 3 by adjusting pointers [OK]
Hint: Find node 3, insert new node by pointer swap [OK]
Common Mistakes:
  • Inserting at wrong position
  • Not updating pointers correctly
  • Replacing head incorrectly
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