Skip to content

Instantly share code, notes, and snippets.

@Gankra
Created March 19, 2015 20:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gankra/155234908dae0d984fe5 to your computer and use it in GitHub Desktop.
Save Gankra/155234908dae0d984fe5 to your computer and use it in GitHub Desktop.
mutable singly-linked list
struct List<T> {
head: Option<Box<Node<T>>>
}
struct Node<T> {
elem: T,
next: Option<Box<Node<T>>>,
}
impl<T> List<T> {
fn push(&mut self, elem: T) {
let new_head = Some(Box::new(Node {
elem: elem,
next: self.head.take(),
}));
self.head = new_head;
}
fn pop(&mut self) -> Option<T> {
self.head.take().map(|mut node| {
self.head = node.next.take();
node.elem
})
}
fn insert(&mut self, index: usize, elem: T) {
if index == 0 {
self.push(elem);
} else {
// get a mutable ref to the option's contents
let mut cur_node = self.head.as_mut().expect("index out of bounds");
// walk the list
for _ in 1..index {
let temp = cur_node; // hack to get borrowck happy
cur_node = temp.next.as_mut().expect("index out of bounds");
}
let new_next = Some(Box::new(Node {
elem: elem,
next: cur_node.next.take(),
}));
cur_node.next = new_next;
}
}
fn remove(&mut self, index: usize) -> T {
if index == 0 {
self.pop().expect("index out of bounds")
} else {
let mut cur_node = self.head.as_mut().expect("index out of bounds");
for _ in 1..index {
let temp = cur_node; // hack to get borrowck happy
cur_node = temp.next.as_mut().expect("index out of bounds");
}
let mut next = cur_node.next.take().expect("index out of bounds");
cur_node.next = next.next.take();
next.elem
}
}
}
impl<T: Eq> List<T> {
fn remove_eq(&mut self, target: &T) -> Option<T> {
match self.head.take() {
None => None,
Some(mut head) => {
if &head.elem == target {
self.head = head.next.take();
Some(head.elem)
} else {
self.head = Some(head);
let mut cur_node = self.head.as_mut().unwrap();
loop {
let temp = cur_node;
let search_step = temp.next.as_ref().map(|next| {
&next.elem == target
});
match search_step {
None => return None,
Some(true) => {
let mut next = temp.next.take().unwrap();
temp.next = next.next.take();
return Some(next.elem);
}
Some(false) => {
cur_node = temp.next.as_mut().unwrap();
}
}
}
}
}
}
}
}
fn main() {
let mut list = List { head: None };
list.push(3);
list.push(2);
list.push(1);
println!("{}", list.pop().unwrap()); // 1
list.insert(2, 5);
list.insert(2, 4);
println!("{}", list.remove(1)); // 3
println!("{}", list.remove(2)); // 5
println!("{}", list.remove_eq(&2).unwrap()); // 2
println!("{}", list.remove_eq(&10).is_none()); // true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment