Circular Linked List
Take a regular linked list and change one thing: instead of the last node pointing to null, have it point right back to the first node. That's a circular linked list — a loop with no real end.
It can be built either as a singly-linked loop (one pointer per node) or a doubly-linked loop (two pointers per node). Because the chain never terminates, it's a natural fit for anything that needs to cycle repeatedly, like round-robin scheduling or a circular buffer.
Since there's no fixed "first" or "last" node anymore, you can start traversing from anywhere in the loop and eventually visit every node — handy for problems that are inherently cyclic rather than linear.
Key Property: The last node's next pointer always points back to the first node, creating a continuous loop.
Basic Operations
| Operation | Complexity | Description |
|---|---|---|
| Insertion at Head | O(1) | Add new node at beginning, point last node to new head |
| Insertion at Tail | O(1) | Add new node at end, point it to head (with tail pointer) |
| Deletion at Head | O(1) | Remove first node, update last node's pointer |
| Deletion by Value | O(n) | Traverse list to find and remove specific node |
| Traversal | O(n) | Loop through nodes until returning to starting point |
| Search | O(n) | Traverse list to find element |
Insertion Process
- Create new node with data
- If list is empty, set head and tail to new node
- Make new node point to itself (circular reference)
- For non-empty list, set new node's next to current head
- Update tail's next pointer to new node
- Move head pointer to new node
Deletion Process
- Check if list is empty
- If single node exists, set head and tail to null
- For head deletion, update head to head.next
- Update tail's next pointer to new head
- For middle deletion, find node and update previous node's pointer
- Handle special case when deleting last node
Operation Visualization
| Operation | List State |
|---|---|
| Initialization | head → null |
| insertFirst(10) | head → [10] → (points back to head) |
| insertFirst(20) | head → [20] → [10] → (points back to head) |
| insertFirst(30) | head → [30] → [20] → [10] → (points back to head) |
| deleteFirst() | head → [20] → [10] → (points back to head) |
| delete(10) | head → [20] → (points back to itself) |
Comparison with Linear Linked List
| Feature | Linear Linked List | Circular Linked List |
|---|---|---|
| Structure | Linear with null termination | Circular with no null |
| Traversal | Stops at end | Continuous loop |
| Memory Overhead | Standard | Same as linear |
| Boundary Detection | Easy (null check) | Requires start reference |
| Insert/Delete at Head | O(1) | O(1) |
| Implementation Complexity | Simpler | More complex |
Applications
- Operating system round-robin scheduling
- Multiplayer turn-based games
- Music/video playlists with repeat functionality
- Resource allocation in networking
- Circular buffer implementations
- Token ring networks
When to Choose: Prefer circular linked lists when you need continuous cycling through elements or when the application naturally follows a circular pattern (like round-robin scheduling).