Mental Model
Add a new item at the very end of a chain by following links until the last one.
Analogy: Like adding a new car to the end of a train by walking to the last car and attaching it there.
Head -> 1 -> 2 -> 3 -> null
↑Head -> 1 -> 2 -> 3 -> null
↑Head -> [curr->1] -> 2 -> 3 -> null
Head -> 1 -> [curr->2] -> 3 -> null
Head -> 1 -> 2 -> [curr->3] -> null
Head -> 1 -> 2 -> 3 -> 4 -> null
Head -> 1 -> 2 -> 3 -> 4 -> null
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { val: i32, next: Option<Rc<RefCell<Node>>>, } impl Node { fn new(val: i32) -> Rc<RefCell<Node>> { Rc::new(RefCell::new(Node { val, next: None })) } } struct LinkedList { head: Option<Rc<RefCell<Node>>>, } impl LinkedList { fn new() -> Self { LinkedList { head: None } } fn insert_at_end(&mut self, val: i32) { let new_node = Node::new(val); if self.head.is_none() { self.head = Some(new_node); return; } let mut curr = self.head.as_ref().unwrap().clone(); // advance curr to last node while curr.borrow().next.is_some() { let next = curr.borrow().next.as_ref().unwrap().clone(); curr = next; } // link new_node at end curr.borrow_mut().next = Some(new_node); } fn print_list(&self) { let mut curr_opt = self.head.clone(); while let Some(curr) = curr_opt { print!("{} -> ", curr.borrow().val); curr_opt = curr.borrow().next.clone(); } println!("null"); } } fn main() { let mut list = LinkedList::new(); list.insert_at_end(1); list.insert_at_end(2); list.insert_at_end(3); list.insert_at_end(4); list.print_list(); }
if self.head.is_none() {
self.head = Some(new_node);
return;
}while curr.borrow().next.is_some() {
let next = curr.borrow().next.as_ref().unwrap().clone();
curr = next;
}curr.borrow_mut().next = Some(new_node);if self.head.is_none() { self.head = Some(new_node); return; }
while curr.borrow().next.is_some() {
let next = curr.borrow().next.as_ref().unwrap().clone();
curr = next;
}struct Node {
value: i32,
next: Option,
}
fn main() {
let mut head: Option = None;
for val in [1, 2, 3] {
let mut current = &mut head;
while current.is_some() {
current = &mut current.as_mut().unwrap().next;
}
*current = Some(Box::new(Node { value: val, next: None }));
}
let mut current = &head;
while let Some(node) = current {
print!("{} -> ", node.value);
current = &node.next;
}
print!("null\n");
}let mut current = &head;
while current.is_some() {
current = ¤t.unwrap().next;
}
*current = Some(Box::new(Node { value: 5, next: None }));Pass the test and this pattern moves unknown