📖 Scenario: Imagine you have a collection of books that you want to organize on a shelf. Sometimes you want to add a new book in the middle without moving all the other books. A linked list helps solve this problem by letting you add or remove items easily without shifting everything.
🎯 Goal: You will create a simple linked list in Rust to understand how it stores data differently from arrays. You will see how adding items works without moving the whole list.
📋 What You'll Learn
Create a linked list node struct called Node with a value and a pointer to the next node
Create a variable called head that points to the first node or is empty
Add a new node at the start of the list
Print the values in the linked list from head to end
💡 Why This Matters
🌍 Real World
Linked lists are used in music players to manage playlists, in operating systems for task scheduling, and in many software systems where dynamic data storage is needed.
💼 Career
Understanding linked lists helps in software development roles that require knowledge of data structures for efficient memory and data management.
Progress0 / 4 steps
1
Create the Node struct and head variable
Create a struct called Node with a field value of type i32 and a field next of type Option>. Then create a variable called head and set it to None.
DSA Rust
Hint
Use Option> for the next field to allow for empty or next nodes.
2
Add a new node at the start
Inside main, create a new Node with value 10 and next pointing to head. Then update head to point to this new node.
DSA Rust
Hint
Use Box::new(Node { ... }) to create a new node on the heap.
3
Add another node at the start
Create another new Node with value 20 and next pointing to head. Update head to this new node so the list has two nodes.
DSA Rust
Hint
Repeat the process to add a second node at the front.
4
Print the linked list values
Use a while let loop with a variable current starting at head.as_ref(). Inside the loop, print current.value and update current to current.next.as_ref(). Print all values separated by arrows -> and end with None.
DSA Rust
Hint
Use as_ref() to get a reference to the node inside the Option.
Practice
(1/5)
1. Why do we use a linked list instead of an array in some cases?
easy
A. Because linked lists store elements in contiguous memory locations
B. Because linked lists use less memory than arrays always
C. Because linked lists allow easy insertion and deletion without shifting elements
D. Because linked lists are faster for accessing elements by index
Solution
Step 1: Understand array limitations and linked list advantages
Arrays store elements in contiguous memory, so inserting or deleting in the middle requires shifting elements, which is slow. Linked lists store elements as nodes linked by pointers, so insertion and deletion can be done by changing pointers without shifting.
Final Answer:
Because linked lists allow easy insertion and deletion without shifting elements -> Option C
Quick Check:
Linked list insertion/deletion ease [OK]
Hint: Linked lists excel at insert/delete without shifting [OK]
Common Mistakes:
Thinking linked lists use less memory always
Believing linked lists store elements contiguously
Assuming linked lists are faster for index access
2. Which of the following is the correct way to define a node struct for a singly linked list in Rust?
easy
A. struct Node { value: i32, next: Box<Node> }
B. struct Node { value: i32, next: Option }
C. struct Node { value: i32, next: &Node }
D. struct Node { value: i32, next: Node }
Solution
Step 1: Recall Rust ownership rules and Option usage
Rust requires recursive types like linked lists to use indirection like Box to allocate on heap. The next pointer can be None if it's the last node, so Option is needed.
Hint: Use Option for next pointer in Rust linked list [OK]
Common Mistakes:
Using next: Node causes infinite size error
Using references (&Node) without lifetime causes errors
Omitting Option causes no way to mark list end
3. What will be the output of the following Rust code that creates a linked list with values 1, 2, 3 and prints them?
struct Node {
value: i32,
next: Option,
}
fn main() {
let third = Node { value: 3, next: None };
let second = Node { value: 2, next: Some(Box::new(third)) };
let first = Node { value: 1, next: Some(Box::new(second)) };
let mut current = &first;
while let Some(ref next_node) = current.next {
println!("{} ->", current.value);
current = next_node;
}
println!("{} -> null", current.value);
}
medium
A. 1 -> 2 -> 3 -> null
B. 3 -> 2 -> 1 -> null
C. 1 -> 2 -> null
D. Compilation error due to ownership
Solution
Step 1: Trace linked list creation and printing loop
Nodes are created in reverse order: third (3), second (2), first (1) linking to next. Loop prints current.value then moves to next node until next is None, printing 1, 2, 3 in order.
Final Answer:
1 -> 2 -> 3 -> null -> Option A
Quick Check:
Print order matches linked list order [OK]
Hint: Follow next pointers to print nodes in order [OK]
Common Mistakes:
Confusing order and printing reversed
Expecting compilation error due to ownership
Stopping loop too early missing last node
4. The following Rust code tries to insert a new node with value 4 at the beginning of a linked list but causes a compilation error. What is the error?
struct Node {
value: i32,
next: Option,
}
fn main() {
let mut first = Node { value: 1, next: None };
let new_node = Node { value: 4, next: Some(Box::new(first)) };
first = new_node;
}
medium
A. Borrow of moved value `first`
B. Cannot assign to `first` because it is not mutable
C. Recursive type has infinite size without Box
D. No error, code compiles fine
Solution
Step 1: Identify actual error
`first` is declared mutable, so assignment should be allowed and Cannot assign to `first` because it is not mutable is incorrect. The error is `first` is moved into `Box::new(first)` when creating `new_node`, but then `first = new_node` tries to use `first` after the move, causing borrow of moved value.
Final Answer:
Borrow of moved value `first` -> Option A
Quick Check:
Ownership move error [OK]
Hint: Check ownership moves when assigning linked nodes [OK]
Common Mistakes:
Confusing mutability error with ownership error
Thinking code compiles fine
Ignoring ownership rules in Rust
5. You want to implement a linked list in Rust that supports efficient insertion at the front and also allows traversing the list. Which of the following best explains why a linked list is preferred over a vector (array) for this use case?
hard
A. Linked lists store elements contiguously, making traversal faster than vectors
B. Vectors allow O(1) insertion at front but linked lists are simpler to implement
C. Vectors use pointers to link elements, so linked lists are redundant
D. Linked lists allow O(1) insertion at front without reallocating or shifting elements
Solution
Step 1: Analyze insertion and traversal complexities
Vectors require shifting elements or reallocating memory for insertion at front, which is O(n). Linked lists insert at front by changing head pointer and new node's next pointer, which is O(1) without shifting. Traversal in linked lists is sequential via pointers; vectors have contiguous memory but insertion cost is higher at front.
Final Answer:
Linked lists allow O(1) insertion at front without reallocating or shifting elements -> Option D
Quick Check:
Insertion cost at front = O(1) linked list [OK]
Hint: Linked list front insertion is O(1), vector front insertion is O(n) [OK]
Common Mistakes:
Thinking vectors insert at front in O(1)
Believing linked lists store elements contiguously
Confusing pointers in vectors with linked list nodes
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.