This is my singly linked list code have to implement pop from end and pop from front functions still, but I'm having difficulty in writing pop from end function
#![allow(warnings)]
#[derive(Clone)]
struct List {
el: i32,
next: Box<Option<List>>
}
impl List {
fn new(val: i32) -> List {
return List {
el: val,
next: Box::new(None)
}
}
fn from(arr: &[i32]) -> List {
let mut head = List::new(arr[0]);
let mut current = &mut head;
for &val in &arr[1..] {
/* current.next = Box::new(Some(List::new(val)));
current = (*current.next).as_mut().unwrap(); */
current.append(val);
}
return head
}
fn append(&mut self, val: i32) {
let mut current = self;
while let Some(ref mut next_node) = *current.next {
current = next_node;
}
current.next = Box::new(Some(List::new(val)));
}
fn prepend(&mut self, val:i32) {
// std::mem::replace(dest, src):
// Moves src into the referenced dest, returning the previous dest value
let old_self = std::mem::replace(self, List::new(val));
self.next = Box::new(Some(old_self));
}
}
fn main() {
let mut list = List::new(42);
list.append(32);
list.append(2321);
list.append(2839);
list.prepend(69);
list.pop(); // 2839 // difficulty in implementing this
println!("{}", list);
let mut list = List::from(&[1, 2, 3]);
list.prepend(0);
println!("{}", list);
}
Should I use Rc
and RefCell
to implement a singly linked list? I'm a beginner, so please help. Thanks!
fn pop(&mut self) -> Option<List> {
match &mut*self.next {
// if self.next is None
// that means that the list only have one element
// and idk what's you desired behavior, but I just return None
None => None,
// we check the next element
Some(n) => {
if n.next.is_none() {
// if the next element is the terminal element
// we take the self.next
// that will change the current.next to None
self.next.take()
}else{
// if the next element is not the terminal element
n.pop()
}
}
}
}
fn main() {
let mut list = List::new(42);
list.append(32);
list.append(2321);
list.append(2839);
list.prepend(69);
println!("{}", list);
println!("{:?}", list.pop());
println!("{}", list);
let mut list = List::from(&[1, 2, 3]);
list.prepend(0);
println!("{}", list);
println!("{:?}",list.pop());
println!("{}", list);
}
LinkedList([69, 42, 32, 2321, 2839])
Some(List { el: 2839, next: None })
LinkedList([69, 42, 32, 2321])
LinkedList([0, 1, 2, 3])
Some(List { el: 3, next: None })
LinkedList([0, 1, 2])
there is this pattern &*self.next
let x: Box<Option<List>> = self.next; // illegal, you cannot move it out
let x: Option<List> = * self.next; // illegal, you cannot move it out
let x: &Option<List> = & * self.next; // legal, you can borrow the value
you can use #[derive(Debug)]
to make debug easier, and don't need to implement Display
all the time.
#[derive(Clone, Debug)]
struct List {
el: i32,
next: Box<Option<List>>
}