Circular linked lists are used in real-time systems like task scheduling where tasks repeat in a cycle.
💼 Career
Understanding circular linked lists and how to manipulate them is important for roles involving system programming, embedded systems, and performance-critical applications.
Progress0 / 4 steps
1
Create the Circular Linked List
Create a struct called Node with a field value of type i32 and a field next which is an Option<Rc<RefCell<Node>>>. Add the necessary use statements. Then create three nodes with values 10, 20, and 30 linked in a circular way. Assign the head node to a variable called head.
DSA Rust
Hint
Remember to link the last node back to the first node to make the list circular. Use Rc and RefCell for shared ownership and mutability.
2
Add the New Value Variable
Create a variable called new_value and set it to 40.
DSA Rust
Hint
Just create a variable named new_value and assign 40 to it.
3
Write the Insert at End Function
Write a function called insert_at_end that takes a reference to a Rc<RefCell<Node>> called head and an i32 called value. The function should insert a new node with value at the end of the circular linked list, maintaining the circular structure. Call the function in main.
DSA Rust
Hint
Traverse the list using a loop until you find the node whose next points back to head (use Rc::ptr_eq). Create the new node pointing to head, and update the last node's next.
4
Print the Circular Linked List
Write code to print the circular linked list starting from head. Print all node values separated by -> and end with null. Use a loop and stop after printing all nodes once to avoid infinite loops.
DSA Rust
Hint
Start from head and print each node's value followed by an arrow. Use Rc::ptr_eq to stop when you reach the head again to avoid infinite loops.
Practice
(1/5)
1. What is the main difference between a circular linked list and a regular singly linked list?
easy
A. In a circular linked list, the last node points back to the first node.
B. In a circular linked list, nodes have two pointers instead of one.
C. In a circular linked list, nodes are stored in an array.
D. In a circular linked list, nodes cannot be inserted at the end.
Solution
Step 1: Understand the structure of a circular linked list
A circular linked list connects the last node back to the first node, forming a circle.
Step 2: Compare with a regular singly linked list
A regular singly linked list ends with a node pointing to null, not back to the first node.
Final Answer:
In a circular linked list, the last node points back to the first node. -> Option A
Quick Check:
Circular linked list last node points to head [OK]
Hint: Remember: circular means last node loops to first [OK]
Common Mistakes:
Thinking circular lists have two pointers per node
Confusing circular linked list with doubly linked list
Assuming circular lists cannot have end insertions
2. Which of the following Rust code snippets correctly creates a new node and inserts it at the end of a circular linked list?
easy
A. let new_node = Node::new(data); new_node.next = None; tail.next = Some(new_node); tail = new_node;
B. let new_node = Node::new(data); new_node.next = head; tail.next = Some(new_node); tail = new_node;
C. let new_node = Node::new(data); new_node.next = tail; head.next = Some(new_node); tail = new_node;
D. let new_node = Node::new(data); new_node.next = head; head.next = Some(new_node); tail = new_node;
Solution
Step 1: Create new node and link to head
In a circular linked list, the new node's next should point to head to maintain the circle.
Step 2: Update tail's next and tail pointer
Tail's next should point to the new node, and tail should be updated to new node.
Final Answer:
let new_node = Node::new(data); new_node.next = head; tail.next = Some(new_node); tail = new_node; -> Option B
Quick Check:
New node points to head, tail updated [OK]
Hint: New node's next must point to head in circular list [OK]
Common Mistakes:
Setting new node's next to None breaks the circle
Linking new node to tail instead of head
Not updating tail pointer after insertion
3. Given the following Rust code for inserting at the end of a circular linked list, what will be the printed output after inserting 4 into the list 1 -> 2 -> 3 -> (back to 1)?
fn print_list(head: &Option) {
let mut temp = head.as_ref();
if temp.is_none() { return; }
let start = temp.unwrap();
loop {
print!("{} -> ", temp.unwrap().data);
temp = temp.unwrap().next.as_ref();
if temp.is_none() || temp.unwrap().data == head.as_ref().unwrap().data { break; }
}
println!("null");
}
// After insertion of 4 at end
// List structure: 1 -> 2 -> 3 -> 4 -> (back to 1)
medium
A. 1 -> 2 -> 3 -> 4 -> 1 -> null
B. 1 -> 2 -> 3 -> null
C. 1 -> 2 -> 3 -> 4 -> null
D. 4 -> 1 -> 2 -> 3 -> null
Solution
Step 1: Understand the print loop logic
The loop prints nodes until it reaches the head again, then breaks to avoid infinite loop.
Step 2: Trace the list after insertion
After inserting 4 at end, list is 1 -> 2 -> 3 -> 4 -> back to 1. The print stops before repeating head.
Final Answer:
1 -> 2 -> 3 -> 4 -> null -> Option C
Quick Check:
Print stops before repeating head [OK]
Hint: Print stops before repeating head node [OK]
Common Mistakes:
Printing the head node twice causing infinite loop
Not breaking loop on head node detection
Confusing order of nodes after insertion
4. The following Rust code attempts to insert a new node at the end of a circular linked list but causes a runtime error. What is the error?
A. Using tail.clone() causes ownership issues leading to runtime panic.
B. Setting new_node.next to None breaks the circular link causing infinite loop.
C. Assigning *tail = tail.as_mut().unwrap().next.clone() causes borrow checker error.
D. Not updating tail pointer after insertion causes stale tail reference.
Solution
Step 1: Analyze tail.clone() usage
Cloning tail (which is an Option) duplicates ownership, which Rust forbids at runtime for Box.
Step 2: Understand Rust ownership rules
Box pointers cannot be cloned freely; this causes runtime panic or compile error due to ownership violation.
Final Answer:
Using tail.clone() causes ownership issues leading to runtime panic. -> Option A
Quick Check:
Cloning Box without proper ownership causes error [OK]
Hint: Avoid cloning Box pointers; use references or Rc instead [OK]
Common Mistakes:
Setting next to None breaking circularity
Ignoring Rust ownership and cloning rules
Not updating tail pointer correctly
5. You have a circular linked list with nodes containing values [10, 20, 30]. You want to insert a new node with value 25 at the end, but also maintain a sorted order in the circular list. Which approach correctly inserts 25 while keeping the list sorted?
hard
A. Replace the last node's value with 25 without changing links.
B. Insert 25 at the end and then sort the entire list.
C. Insert 25 at the head and update tail to new node.
D. Traverse the list to find the correct position and insert 25 there, updating links accordingly.
Solution
Step 1: Understand sorted circular linked list insertion
To keep the list sorted, find the correct position where 25 fits between nodes.
Step 2: Insert node at correct position and update links
Traverse nodes until finding node with value less than 25 and next node greater than 25, then insert new node there.
Step 3: Update tail if inserted at end
If inserted after the current tail, update tail pointer to new node to maintain list integrity.
Final Answer:
Traverse the list to find the correct position and insert 25 there, updating links accordingly. -> Option D
Quick Check:
Insert at sorted position to keep order [OK]
Hint: Insert at correct sorted position, not just at end [OK]
Common Mistakes:
Inserting at end without sorting breaks order
Replacing node value loses data integrity
Not updating tail when inserting at end
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.