A circular linked list connects the last node back to the first node, allowing continuous traversal without a null end. This is not possible in a singly linked list.
A music playlist that loops back to the first song after the last one is a classic example of a circular linked list in use.
use std::rc::Rc;
use std::cell::RefCell;
struct Node {
value: i32,
next: Option<Rc<RefCell<Node>>>,
}
fn main() {
let first = Rc::new(RefCell::new(Node { value: 1, next: None }));
let second = Rc::new(RefCell::new(Node { value: 2, next: None }));
let third = Rc::new(RefCell::new(Node { value: 3, next: None }));
first.borrow_mut().next = Some(second.clone());
second.borrow_mut().next = Some(third.clone());
third.borrow_mut().next = Some(first.clone()); // circular link
let mut current = first.clone();
for _ in 0..5 {
print!("{} -> ", current.borrow().value);
let next = current.borrow().next.clone().unwrap();
current = next;
}
print!("null");
}The loop runs 5 times, printing the values of nodes in order: 1, 2, 3, 1, 2, then stops. The printed output ends with 'null'.
use std::rc::Rc;
use std::cell::RefCell;
struct Node {
value: i32,
next: Option<Rc<RefCell<Node>>>,
}
fn main() {
let first = Rc::new(RefCell::new(Node { value: 1, next: None }));
let second = Rc::new(RefCell::new(Node { value: 2, next: None }));
first.borrow_mut().next = Some(second.clone());
second.borrow_mut().next = Some(second.clone()); // circular link to itself
let mut current = first.clone();
for _ in 0..3 {
print!("{} -> ", current.borrow().value);
let next = current.borrow().next.clone().unwrap();
current = next;
}
print!("null");
}The second node points to itself, so traversal prints 1, then 2, then 2 again, then stops after 3 iterations.
Circular linked lists let the game cycle through players continuously, making it easy to move from the last player back to the first without extra code.
