Building a Linked List with Self-Referential Structs in Rust
Creating self-referential data structures, like linked lists, is a fundamental concept in computer science. In Rust, due to its strong memory safety guarantees, handling such structures requires careful consideration of ownership and borrowing rules. This challenge will guide you through implementing a singly linked list using a self-referential struct.
Problem Description
Your task is to define a Rust struct that can represent a node in a singly linked list. Each node should contain a data value and a pointer to the next node in the sequence. This means the struct will refer to itself, which is the core of a self-referential structure. You will then implement basic functionality to create and traverse such a list.
Key Requirements:
- Define a struct named
Nodethat can hold an integer (i32) and a reference to anotherNode. - The
Nodestruct's "next" field must be able to point toNone(representing the end of the list) or anotherNode. - Implement a function
create_listthat takes aVec<i32>and constructs a linked list from it. The last node should point toNone. - Implement a function
print_listthat takes the head of the list and prints all the values in order.
Expected Behavior:
When create_list is called with a vector of integers, it should return the head of a correctly formed linked list. When print_list is called with the head of a list, it should output the values sequentially, separated by " -> ". The output should end with "None".
Edge Cases:
- An empty input vector for
create_listshould result in an empty list (returningNone). - A list with a single element.
Examples
Example 1:
Input: vec![1, 2, 3]
Output: 1 -> 2 -> 3 -> None
Explanation: The input vector is used to build a linked list. The first node contains 1 and points to a node containing 2, which points to a node containing 3, which finally points to None.
Example 2:
Input: vec![]
Output: None
Explanation: An empty input vector results in an empty linked list, represented by None.
Example 3:
Input: vec![42]
Output: 42 -> None
Explanation: A list with a single element correctly terminates with None.
Constraints
- The data values stored in the nodes will be of type
i32. - The input to
create_listwill be aVec<i32>. - The output of
print_listshould be a string representation as described in Expected Behavior.
Notes
Remember that Rust's ownership and borrowing rules are critical here. You'll likely need to use Box to allocate nodes on the heap, enabling recursive data structures, and Option to handle the possibility of a node not having a successor. Consider how you'll manage the lifetimes and mutability of your node references. A common approach involves using Option<Box<Node>> for the "next" pointer.