From 1e4049204e1b355ba10a6abc4b67bc47cc10b5b6 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Sat, 25 Feb 2023 10:41:19 +0000 Subject: [PATCH] part 2 except iterator --- week3/linked_list/src/linked_list.rs | 69 +++++++++++++++++++++------- week3/linked_list/src/main.rs | 6 +++ 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/week3/linked_list/src/linked_list.rs b/week3/linked_list/src/linked_list.rs index c3a36d6..7527a1d 100644 --- a/week3/linked_list/src/linked_list.rs +++ b/week3/linked_list/src/linked_list.rs @@ -1,24 +1,24 @@ use std::fmt; use std::option::Option; -pub struct LinkedList { - head: Option>, +pub struct LinkedList { + head: Option>>, size: usize, } -struct Node { - value: u32, - next: Option>, +struct Node { + value: T, + next: Option>>, } -impl Node { - pub fn new(value: u32, next: Option>) -> Node { +impl Node { + pub fn new(value: T, next: Option>>) -> Node { Node {value: value, next: next} } } -impl LinkedList { - pub fn new() -> LinkedList { +impl LinkedList { + pub fn new() -> LinkedList { LinkedList {head: None, size: 0} } @@ -30,24 +30,26 @@ impl LinkedList { self.get_size() == 0 } - pub fn push_front(&mut self, value: u32) { - let new_node: Box = Box::new(Node::new(value, self.head.take())); + pub fn push_front(&mut self, value: T) { + let new_node: Box> = Box::new(Node::new(value, self.head.take())); self.head = Some(new_node); self.size += 1; } - pub fn pop_front(&mut self) -> Option { - let node: Box = self.head.take()?; + pub fn pop_front(&mut self) -> Option { + let node: Box> = self.head.take()?; self.head = node.next; self.size -= 1; Some(node.value) } + + } -impl fmt::Display for LinkedList { +impl fmt::Display for LinkedList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut current: &Option> = &self.head; + let mut current: &Option>> = &self.head; let mut result = String::new(); loop { match current { @@ -62,7 +64,7 @@ impl fmt::Display for LinkedList { } } -impl Drop for LinkedList { +impl Drop for LinkedList { fn drop(&mut self) { let mut current = self.head.take(); while let Some(mut node) = current { @@ -71,5 +73,40 @@ impl Drop for LinkedList { } } +impl Clone for Node { + fn clone(&self) -> Self { + Node::new(self.value.clone(), self.next.clone()) + } +} +impl Clone for LinkedList { + fn clone(&self) -> LinkedList { + let mut copy_list = LinkedList::new(); + copy_list.size = self.size; + copy_list.head = self.head.clone(); + // tricky recursive clone, Option clone-> Box clone-> Node clone -> Node.next clone(Box clone) + // I tried to implement tail-insertion, but it is impossible to realize that without unsafe... + copy_list + } +} + +impl PartialEq for LinkedList { + fn eq(&self, other: &Self) -> bool { + if self.size != other.size { + return false; + } + let mut ptr = & self.head; + let mut ptr_other = & other.head; + while let Some(node) = ptr { + // well, as their size are the same, it's fine to assume that they reach the end at the same time + let node_other = ptr_other.as_ref().unwrap(); + if node_other.value != node.value { + return false; + } + ptr = &node.next; + ptr_other = &node_other.next; + } + true + } +} diff --git a/week3/linked_list/src/main.rs b/week3/linked_list/src/main.rs index 04226e9..981d23e 100644 --- a/week3/linked_list/src/main.rs +++ b/week3/linked_list/src/main.rs @@ -15,6 +15,12 @@ fn main() { println!("size: {}", list.get_size()); println!("{}", list.to_string()); // ToString impl for anything impl Display + let mut list2 = list.clone(); + println!("Right after clone: list == list2 ?= {}", list == list2); + list2.pop_front(); + println!("list2.pop_front: {}", list2); + println!("list == list2 ?= {}", list == list2); + // If you implement iterator trait: //for val in &list { // println!("{}", val);