From 8bbd7a5ff25e7cf7b81a6920901feb7480f7ae18 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Thu, 30 May 2024 17:51:24 +0200 Subject: [PATCH] Modified Lists - added tests - clearer impl --- src/es06_list.rs | 113 ++++++++++++++++----------------------- src/es07_list_generic.rs | 93 +++++++++----------------------- tests/esercizi.rs | 1 + 3 files changed, 73 insertions(+), 134 deletions(-) diff --git a/src/es06_list.rs b/src/es06_list.rs index e75733d..73086ba 100644 --- a/src/es06_list.rs +++ b/src/es06_list.rs @@ -92,63 +92,52 @@ impl LinkedList { pub fn push_front(&mut self, element: T) { let element = Node::new(element).as_memref(); - if let Some(head) = self.head.as_ref() { - Node::get(head).prev = Some(element.clone()); - Node::get(&element).next = Some(head.clone()); - } - if let None = self.tail.as_ref() { + if let Some(head) = self.head.take() { + Node::get(&head).prev = Some(element.clone()); + Node::get(&element).next = Some(head); + } else { self.tail = Some(element.clone()); } - self.head = Some(element.clone()); + self.head = Some(element); self.size += 1; } pub fn push_back(&mut self, element: T) { let element = Node::new(element).as_memref(); - if let Some(tail) = self.tail.as_ref() { - Node::get(tail).next = Some(element.clone()); - Node::get(&element).prev = Some(tail.clone()); - } - if let None = self.tail.as_ref() { + if let Some(tail) = self.tail.take() { + Node::get(&tail).next = Some(element.clone()); + Node::get(&element).prev = Some(tail); + } else { self.head = Some(element.clone()); } - self.tail = Some(element.clone()); + self.tail = Some(element); self.size += 1; } pub fn pop_front(&mut self) -> Option { - self.pop(true) + if let Some(node) = self.head.take() { + let node = Node::get(&node); + self.head = node.next.clone(); + + match self.head.as_ref() { + Some(other) => Node::get(other).prev = None, + _ => self.tail = None, + } + + self.size -= 1; + return Some(node.element); + } + None } pub fn pop_back(&mut self) -> Option { - self.pop(false) - } - fn pop(&mut self, from_head: bool) -> Option { - let ptr = if from_head { - &mut self.head - } else { - &mut self.tail - }; - - if let Some(node) = ptr.clone() { + if let Some(node) = self.tail.take() { let node = Node::get(&node); + self.tail = node.prev.clone(); - let other = if from_head { - node.next.clone() - } else { - node.prev.clone() - }; - - if let Some(node) = other.clone() { - *ptr = other; - if from_head { - Node::get(&node).prev = None; - } else { - Node::get(&node).next = None; - } - } else { - self.head = None; - self.tail = None; + match self.tail.as_ref() { + Some(other) => Node::get(other).next = None, + _ => self.head = None, } self.size -= 1; @@ -158,27 +147,19 @@ impl LinkedList { } pub fn get_front(&self) -> Option { - match self.head.clone() { - Some(head) => Some(Node::get(&head).element), - _ => None, - } + self.head.clone().and_then(|h| Some(Node::get(&h).element)) } pub fn get_back(&self) -> Option { - match self.tail.clone() { - Some(tail) => Some(Node::get(&tail).element), - _ => None, - } + self.tail.clone().and_then(|t| Some(Node::get(&t).element)) } pub fn get(&self, n: i32) -> Option { - if self.size > 0 { - let index = n + if n < 0 { self.size as i32 } else { 0 }; - if let Some(node) = self.find(index) { - return Some(Node::get(&node).element); - } + let index = n + if n < 0 { self.size as i32 } else { 0 }; + if let Some(node) = self.find(index) { + Some(Node::get(&node).element) + } else { + None } - - None } fn find(&self, index: i32) -> Pointer> { @@ -191,18 +172,18 @@ impl LinkedList { let from_head = index <= delta_back; let node = if from_head { &self.head } else { &self.tail }; - let index = if from_head { index } else { delta_back }; - Self::find_node(node, index, from_head) - } - fn find_node(node: &Pointer>, index: usize, from_head: bool) -> Pointer> { - if let Some(node) = node { - return if index == 0 { - Some(node.clone()) - } else { - let node = node.as_ref().borrow(); - let node = if from_head { &node.next } else { &node.prev }; - Self::find_node(node, index - 1, from_head) - }; + let mut node = node.clone(); + let mut index = if from_head { index } else { delta_back }; + + while let Some(curr) = node { + if index == 0 { + return Some(curr.clone()); + } + + let curr = curr.as_ref().borrow(); + let curr = if from_head { &curr.next } else { &curr.prev }; + node = curr.clone(); + index -= 1; } None } diff --git a/src/es07_list_generic.rs b/src/es07_list_generic.rs index cc8fbd4..9d9a751 100644 --- a/src/es07_list_generic.rs +++ b/src/es07_list_generic.rs @@ -95,82 +95,39 @@ impl LinkedList { pub fn push_front(&mut self, element: T) { let element = Node::new(element).as_memref(); - if let Some(head) = self.head.as_ref() { - Node::get(head).prev = Some(element.clone()); - Node::get(&element).next = Some(head.clone()); - } - if let None = self.tail.as_ref() { + if let Some(head) = self.head.take() { + Node::get(&head).prev = Some(element.clone()); + Node::get(&element).next = Some(head); + } else { self.tail = Some(element.clone()); } - self.head = Some(element.clone()); + self.head = Some(element); self.size += 1; } pub fn push_back(&mut self, element: T) { let element = Node::new(element).as_memref(); - if let Some(tail) = self.tail.as_ref() { - Node::get(tail).next = Some(element.clone()); - Node::get(&element).prev = Some(tail.clone()); - } - if let None = self.tail.as_ref() { + if let Some(tail) = self.tail.take() { + Node::get(&tail).next = Some(element.clone()); + Node::get(&element).prev = Some(tail); + } else { self.head = Some(element.clone()); } - self.tail = Some(element.clone()); + self.tail = Some(element); self.size += 1; } pub fn pop_front(&mut self) -> Option { - self.pop(true) + self.get(0) } pub fn pop_back(&mut self) -> Option { - self.pop(false) - } - fn pop(&mut self, from_head: bool) -> Option { - let ptr = if from_head { - &mut self.head - } else { - &mut self.tail - }; - - if let Some(node) = ptr.clone() { - let mut node = Node::get(&node); - - let other = if from_head { - node.next.clone() - } else { - node.prev.clone() - }; - - if let Some(node) = other.clone() { - *ptr = other; - if from_head { - Node::get(&node).prev = None; - } else { - Node::get(&node).next = None; - } - } else { - self.head = None; - self.tail = None; - } - - self.size -= 1; - return mem::take(&mut node.element); - } - None + self.get(-1) } pub fn get(&mut self, n: i32) -> Option { - if self.size == 0 { - return None; - } - let index = n + if n < 0 { self.size as i32 } else { 0 }; - if index == 0 { - self.pop_front() - } else if (index - 1) as usize == self.size { - self.pop_back() - } else if let Some(node) = self.find(index) { + if let Some(node) = self.find(index) { let mut node = Node::get(&node); let prev = node.prev.clone(); let next = node.next.clone(); @@ -201,18 +158,18 @@ impl LinkedList { let from_head = index <= delta_back; let node = if from_head { &self.head } else { &self.tail }; - let index = if from_head { index } else { delta_back }; - Self::find_node(node, index, from_head) - } - fn find_node(node: &Pointer>, index: usize, from_head: bool) -> Pointer> { - if let Some(node) = node { - return if index == 0 { - Some(node.clone()) - } else { - let node = node.as_ref().borrow(); - let node = if from_head { &node.next } else { &node.prev }; - Self::find_node(node, index - 1, from_head) - }; + let mut node = node.clone(); + let mut index = if from_head { index } else { delta_back }; + + while let Some(curr) = node { + if index == 0 { + return Some(curr.clone()); + } + + let curr = curr.as_ref().borrow(); + let curr = if from_head { &curr.next } else { &curr.prev }; + node = curr.clone(); + index -= 1; } None } diff --git a/tests/esercizi.rs b/tests/esercizi.rs index 829a539..5efdeb0 100644 --- a/tests/esercizi.rs +++ b/tests/esercizi.rs @@ -3,4 +3,5 @@ pub mod es02_rational; pub mod es04_rational_traits; pub mod es05_bank; pub mod es06_list; +pub mod es07_list_generic; pub mod es08_folds;