📖 Scenario: Imagine you are organizing a group of friends sitting around a table. You want to keep track of who sits next to whom. Sometimes the friends sit in a straight line, and sometimes they sit in a circle.
🎯 Goal: You will create two types of linked lists in Rust: a linear linked list where the last friend points to no one, and a circular linked list where the last friend points back to the first friend. You will then print the order of friends to see the difference.
📋 What You'll Learn
Create a linear linked list with three nodes named 'Alice', 'Bob', and 'Charlie'.
Create a circular linked list with three nodes named 'Alice', 'Bob', and 'Charlie'.
Traverse and print the linear linked list showing the order ending with 'None'.
Traverse and print the circular linked list showing the order looping back to 'Alice'.
💡 Why This Matters
🌍 Real World
Linked lists are used in real life to organize sequences where order matters, like playlists or waiting lines. Circular linked lists are useful when the sequence repeats, like players taking turns in a game.
💼 Career
Understanding linked lists is fundamental for software developers, especially in systems programming, game development, and performance-critical applications where memory management and data structure efficiency matter.
Progress0 / 4 steps
1
Create a linear linked list with three nodes
Create a struct called Node with a name field of type String and a next field of type Option>. Then create three nodes named alice, bob, and charlie with names 'Alice', 'Bob', and 'Charlie' respectively, linking them linearly so that alice.next points to bob, bob.next points to charlie, and charlie.next is None.
DSA Rust
Hint
Use Option> for the next field to allow linking nodes. The last node's next should be None.
2
Create a circular linked list with three nodes
Create a struct called CircularNode with a name field of type String and a next field of type Option>. Then create three nodes named alice_c, bob_c, and charlie_c with names 'Alice', 'Bob', and 'Charlie' respectively, linking them circularly so that alice_c.next points to bob_c, bob_c.next points to charlie_c, and charlie_c.next points back to alice_c.
DSA Rust
Hint
Use mut variables to allow setting next fields after creation. Link the last node's next back to the first node to form a circle.
3
Traverse and print the linear linked list
Write a while loop to traverse the linear linked list starting from alice. Use a variable current of type &Node to move through the list. Print each node's name followed by ' -> '. After the last node, print 'None'.
DSA Rust
Hint
Use a while let loop to check if current.next exists. Print the current node's name and move to the next node until you reach the end.
4
Traverse and print the circular linked list
Write code to traverse the circular linked list starting from alice_c. Use a variable current_c of type &CircularNode. Print each node's name followed by ' -> '. Stop traversal when you reach alice_c again to avoid infinite loop. Then print the first node's name again to show the circle.
DSA Rust
Hint
Use a loop to traverse the circular list. Stop when you reach the starting node again to avoid infinite loops. Print the names with arrows to show the circle.
Practice
(1/5)
1. What is the main difference between a circular linked list and a linear linked list?
easy
A. In a circular linked list, the last node points back to the first node, forming a loop.
B. In a circular linked list, nodes are stored in an array.
C. In a linear linked list, nodes point to multiple next nodes.
D. In a linear linked list, the last node points back to the first node.
Solution
Step 1: Understand the structure of a linear linked list
A linear linked list has nodes connected one after another, and the last node points to null, meaning the list ends.
Step 2: Understand the structure of a circular linked list
In a circular linked list, the last node points back to the first node, creating a loop with no null end.
Final Answer:
In a circular linked list, the last node points back to the first node, forming a loop. -> Option A
Quick Check:
Circular list loops back = D [OK]
Hint: Circular loops back to start; linear ends with null [OK]
Common Mistakes:
Thinking circular lists store nodes in arrays
Believing linear lists loop back to start
Confusing multiple next nodes with circular structure
2. Which of the following Rust code snippets correctly creates a circular linked list node pointing to itself?
easy
A. let mut node = Node { data: 5, next: None }; node.next = Some(Box::new(node.clone()));
B. let node = Node { data: 5, next: None };
C. let mut node = Node { data: 5, next: None }; node.next = Some(Box::new(node));
D. let node = Node { data: 5, next: Some(Box::new(node)) };
Solution
Step 1: Understand Rust ownership and self-referencing
Rust does not allow direct self-referencing without cloning or using smart pointers carefully.
Step 2: Analyze each option for correctness
let node = Node { data: 5, next: None }; has next as None, so no circular link. let node = Node { data: 5, next: Some(Box::new(node)) }; tries to use node before it's fully created, causing error. let mut node = Node { data: 5, next: None }; node.next = Some(Box::new(node)); tries to assign node.next to node itself, which is invalid due to ownership. let mut node = Node { data: 5, next: None }; node.next = Some(Box::new(node.clone())); clones node and assigns it to next, creating a circular reference.
Final Answer:
let mut node = Node { data: 5, next: None }; node.next = Some(Box::new(node.clone())); -> Option A
Quick Check:
Clone node for circular link = B [OK]
Hint: Clone node to point next to itself in Rust [OK]
Common Mistakes:
Assigning next before node is fully created
Using None for next in circular list
Ignoring Rust ownership rules
3. Given the following Rust code for a circular linked list with three nodes, what will be printed when traversing starting from head and printing data 4 times?
#[derive(Clone)]
struct Node {
data: i32,
next: Option<Box<Node>>,
}
fn main() {
let node3 = Node { data: 3, next: None };
let node2 = Node { data: 2, next: Some(Box::new(node3)) };
let mut node1 = Node { data: 1, next: Some(Box::new(node2)) };
// Making circular
let cloned_head = node1.clone();
node1.next.as_mut().unwrap().next.as_mut().unwrap().next = Some(Box::new(cloned_head));
let mut current = &node1;
for _ in 0..4 {
println!("{}", current.data);
current = current.next.as_ref().unwrap();
}
}
medium
A. 1 2 3 None
B. 1 2 3 3
C. 1 2 3 2
D. 1 2 3 1
Solution
Step 1: Understand the linked list structure
Nodes 1, 2, 3 are linked linearly first. Then node3.next points back to the first node, making it circular.
Step 2: Trace the traversal for 4 prints
Starting at node1: print 1, move to node2: print 2, move to node3: print 3, move to node1 again (due to circular): print 1.
Final Answer:
1 2 3 1 -> Option D
Quick Check:
Circular list loops back to start = 1 2 3 1 [OK]
Hint: Circular list repeats nodes after last one [OK]
Common Mistakes:
Assuming last node points to None
Printing wrong node data on loop
Confusing node references in Rust
4. Identify the error in this Rust code snippet that tries to create a circular linked list:
A. Node struct fields are private and inaccessible
B. Missing semicolon after node1.next assignment
C. Cannot assign node2.next after moving node2 into node1.next
D. Rust does not allow Box pointers in structs
Solution
Step 1: Understand ownership and moves in Rust
When node2 is moved into node1.next via Box::new(node2), node2 is no longer accessible in main.
Step 2: Identify the error in node2.next assignment
Trying to assign node2.next after moving node2 causes a compile-time error because node2 is moved and cannot be used again.
Final Answer:
Cannot assign node2.next after moving node2 into node1.next -> Option C
Quick Check:
Ownership moved node2, cannot use again = C [OK]
Hint: Moved value can't be used again in Rust [OK]
Common Mistakes:
Ignoring Rust ownership and move rules
Assuming variables remain usable after move
Confusing Box pointer usage
5. You want to implement a function in Rust that detects if a linked list is circular or linear. Which approach correctly uses the key difference to detect a circular linked list?
hard
A. Count nodes and if count exceeds 10, assume circular.
B. Traverse nodes and check if any node's next pointer points back to the head node.
C. Check if the last node's next pointer is None to confirm circularity.
D. Use recursion to print all nodes until a null pointer is found.
Solution
Step 1: Recall the key difference between circular and linear lists
In circular lists, the last node points back to the head or some earlier node, forming a loop. In linear lists, the last node points to None.
Step 2: Choose the correct detection method
Checking if any node's next points back to the head detects circularity. Counting nodes or checking for None incorrectly assumes circularity or linearity. Recursion may cause infinite loops on circular lists.
Final Answer:
Traverse nodes and check if any node's next pointer points back to the head node. -> Option B
Quick Check:
Loop back to head means circular = A [OK]
Hint: Detect loop by checking if next points to head [OK]
Common Mistakes:
Assuming node count alone detects circularity
Checking last node's next for None means circular
Using recursion without loop detection
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.