Singly circular link list: create, traverse, insert, delete node

The circular list keeps a reference to the LAST node (so last.next is the head), inserts at either end by rewiring 2 links, traverses with do-while, and its single-node case points at itself.

12 min read · 9 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

The roster closes the circle

Final BookBridge build: the reading-room roster. Four members share 2 desks; after Zoya's turn the roster hands the desk back to Riya. Forever.

Last lesson's IssueList cannot express this: its tail says null, full stop. Today the tail says "go back to the start", and every operation must respect one new reality: there is no null to lean on. Create, traverse, insert, delete: same 4 verbs, rewired for a world without an end.

Theory

One clever choice before any code

Which node should the class remember? Instinct says the head. The professionals keep the last node instead, and it buys 2 ends for the price of 1:

  • the head is always reachable instantly: last.next
  • the tail is last itself

So inserting at the FRONT and at the END both need no walking at all: both happen where last already stands. A singly list offering that would have to walk its whole chain for every append.

Practical

The roster, wired as a circle

class CNode {
    String name;
    CNode next;
    CNode(String n) { name = n; }
}

class Roster {
    CNode last;                        // last.next IS the head

    void addLast(String name) {        // join at the end of the circle
        CNode n = new CNode(name);
        if (last == null) {
            last = n;
            n.next = n;                // points at ITSELF: smallest circle
        } else {
            n.next = last.next;        // 1: n grabs the head
            last.next = n;             // 2: old last points at n
            last = n;                  // 3: n becomes the new last
        }
    }

    void traverse() {                  // print each member exactly once
        if (last == null) return;
        CNode cur = last.next;         // start at the head
        do {
            System.out.println(cur.name);
            cur = cur.next;
        } while (cur != last.next);    // stop when the head reappears
    }

    void deleteFirst() {               // the head leaves the circle
        if (last == null) return;
        if (last.next == last) { last = null; return; }  // only node
        last.next = last.next.next;    // bypass the head
    }
}

Theory

Trace: the circle grows

addLast("Riya") on empty: last = Riya, and Riya.next = Riya. One node, pointing at itself: a complete, legal circle.

addLast("Aman"): step 1, Aman.next = last.next (= Riya, the head); step 2, Riya.next = Aman; step 3, last = Aman.

Circle: Riya → Aman → Riya...

addLast("Zoya"): Zoya.next = Riya; Aman.next = Zoya; last = Zoya.

Circle: Riya → Aman → Zoya → back to Riya. traverse() starts at last.next (Riya) and prints Riya, Aman, Zoya, then meets Riya again and stops.

Quiz

In the Roster class, what does the very FIRST node's next point to, immediately after addLast("Riya") on an empty roster?

  1. null, until a second member joins
  2. The node itself: Riya.next == Riya
  3. The last reference of the Roster object
  4. It is left unassigned, so reading it is a compile error
Show the answer

The node itself: Riya.next == Riya

A circular list must ALWAYS close its circle, even with one member: n.next = n makes the smallest possible loop, so traverse and every other operation work without special-casing "circle of 1". Option A would make it a singly list and instantly break the do-while (it would walk into null). Option C confuses a field of the Roster with a node in the chain. Option D forgets Unit 2: fields default to null, and the constructor here explicitly assigns next anyway.

Think first

Trace the exit

Roster: Riya → Aman → Zoya (last = Zoya). Call deleteFirst(), then traverse(). Walk every reference before tapping: who is printed, and what does Zoya.next hold now?

Show the answer

deleteFirst runs last.next = last.next.next: Zoya.next was Riya, Riya.next is Aman, so Zoya.next = Aman. Riya has no incoming reference left: garbage-collected. The circle is Aman → Zoya → Aman, and traverse prints Aman, Zoya. Note what never happened: no walking, no null checks, one reassignment. And if the roster had held only Riya, the guard last.next == last would have fired and set last = null: the circle of 1 empties to nothing.

Watch out

Circle-specific traps

while (cur != null): loops forever; no next in a healthy circle is ever null. The stop test is positional: back at the start.

Plain while instead of do-while: while (cur != last.next) is false before the first print (cur IS the head), so nothing prints. The body-first loop is not optional here.

Deleting last itself: bypassing is not enough; last must move to the node BEFORE it, and finding that node in a singly circle means walking almost all the way around.

Theory

BookBridge, complete

Step back and look at what the semester built: one console app that grew variables into a Book class, a Person family with polymorphism, guarded Strings and a custom exception, a background reminder thread, shelved packages, and now 2 hand-built lists running its queues. That is BCA403's whole syllabus living in one program. The circular pattern itself returns wherever turns repeat: BCA203's round-robin scheduler, playlists on repeat, and multiplayer game loops.

Summary

Key takeaways

  • Keep a reference to the LAST node: last.next is the head, so both ends are reachable without walking.
  • First node of a circle points at itself: n.next = n.
  • Insert at end: n.next = last.next, last.next = n, last = n (front insert: same 2 rewires, skip moving last).
  • Traverse with do-while from last.next, stopping when the head reappears; while-null never terminates.
  • deleteFirst: last.next = last.next.next; a single-node circle empties to last = null.
  • Deleting last itself means walking to its predecessor and moving last there.
  • Memory hook: the circle of one points at itself; the loop that waits for null waits forever.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Data Structure Implementation using Java Class

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Singly circular link list: create, traverse, insert, delete node · Java Programming Language · Gri-Learn