Modified Lists

- added tests
- clearer impl
This commit is contained in:
2024-05-30 17:51:24 +02:00
parent aad7db4a55
commit 8bbd7a5ff2
3 changed files with 73 additions and 134 deletions

View File

@@ -92,63 +92,52 @@ impl<T: Copy> LinkedList<T> {
pub fn push_front(&mut self, element: T) { pub fn push_front(&mut self, element: T) {
let element = Node::new(element).as_memref(); let element = Node::new(element).as_memref();
if let Some(head) = self.head.as_ref() { if let Some(head) = self.head.take() {
Node::get(head).prev = Some(element.clone()); Node::get(&head).prev = Some(element.clone());
Node::get(&element).next = Some(head.clone()); Node::get(&element).next = Some(head);
} } else {
if let None = self.tail.as_ref() {
self.tail = Some(element.clone()); self.tail = Some(element.clone());
} }
self.head = Some(element.clone()); self.head = Some(element);
self.size += 1; self.size += 1;
} }
pub fn push_back(&mut self, element: T) { pub fn push_back(&mut self, element: T) {
let element = Node::new(element).as_memref(); let element = Node::new(element).as_memref();
if let Some(tail) = self.tail.as_ref() { if let Some(tail) = self.tail.take() {
Node::get(tail).next = Some(element.clone()); Node::get(&tail).next = Some(element.clone());
Node::get(&element).prev = Some(tail.clone()); Node::get(&element).prev = Some(tail);
} } else {
if let None = self.tail.as_ref() {
self.head = Some(element.clone()); self.head = Some(element.clone());
} }
self.tail = Some(element.clone()); self.tail = Some(element);
self.size += 1; self.size += 1;
} }
pub fn pop_front(&mut self) -> Option<T> { pub fn pop_front(&mut self) -> Option<T> {
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<T> { pub fn pop_back(&mut self) -> Option<T> {
self.pop(false) if let Some(node) = self.tail.take() {
}
fn pop(&mut self, from_head: bool) -> Option<T> {
let ptr = if from_head {
&mut self.head
} else {
&mut self.tail
};
if let Some(node) = ptr.clone() {
let node = Node::get(&node); let node = Node::get(&node);
self.tail = node.prev.clone();
let other = if from_head { match self.tail.as_ref() {
node.next.clone() Some(other) => Node::get(other).next = None,
} else { _ => self.head = None,
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; self.size -= 1;
@@ -158,28 +147,20 @@ impl<T: Copy> LinkedList<T> {
} }
pub fn get_front(&self) -> Option<T> { pub fn get_front(&self) -> Option<T> {
match self.head.clone() { self.head.clone().and_then(|h| Some(Node::get(&h).element))
Some(head) => Some(Node::get(&head).element),
_ => None,
}
} }
pub fn get_back(&self) -> Option<T> { pub fn get_back(&self) -> Option<T> {
match self.tail.clone() { self.tail.clone().and_then(|t| Some(Node::get(&t).element))
Some(tail) => Some(Node::get(&tail).element),
_ => None,
}
} }
pub fn get(&self, n: i32) -> Option<T> { pub fn get(&self, n: i32) -> Option<T> {
if self.size > 0 {
let index = n + if n < 0 { self.size as i32 } else { 0 }; let index = n + if n < 0 { self.size as i32 } else { 0 };
if let Some(node) = self.find(index) { if let Some(node) = self.find(index) {
return Some(Node::get(&node).element); Some(Node::get(&node).element)
} } else {
}
None None
} }
}
fn find(&self, index: i32) -> Pointer<Node<T>> { fn find(&self, index: i32) -> Pointer<Node<T>> {
if index < 0 || index as usize >= self.size { if index < 0 || index as usize >= self.size {
@@ -191,18 +172,18 @@ impl<T: Copy> LinkedList<T> {
let from_head = index <= delta_back; let from_head = index <= delta_back;
let node = if from_head { &self.head } else { &self.tail }; let node = if from_head { &self.head } else { &self.tail };
let index = if from_head { index } else { delta_back }; let mut node = node.clone();
Self::find_node(node, index, from_head) let mut index = if from_head { index } else { delta_back };
while let Some(curr) = node {
if index == 0 {
return Some(curr.clone());
} }
fn find_node(node: &Pointer<Node<T>>, index: usize, from_head: bool) -> Pointer<Node<T>> {
if let Some(node) = node { let curr = curr.as_ref().borrow();
return if index == 0 { let curr = if from_head { &curr.next } else { &curr.prev };
Some(node.clone()) node = curr.clone();
} else { index -= 1;
let node = node.as_ref().borrow();
let node = if from_head { &node.next } else { &node.prev };
Self::find_node(node, index - 1, from_head)
};
} }
None None
} }

View File

@@ -95,82 +95,39 @@ impl<T> LinkedList<T> {
pub fn push_front(&mut self, element: T) { pub fn push_front(&mut self, element: T) {
let element = Node::new(element).as_memref(); let element = Node::new(element).as_memref();
if let Some(head) = self.head.as_ref() { if let Some(head) = self.head.take() {
Node::get(head).prev = Some(element.clone()); Node::get(&head).prev = Some(element.clone());
Node::get(&element).next = Some(head.clone()); Node::get(&element).next = Some(head);
} } else {
if let None = self.tail.as_ref() {
self.tail = Some(element.clone()); self.tail = Some(element.clone());
} }
self.head = Some(element.clone()); self.head = Some(element);
self.size += 1; self.size += 1;
} }
pub fn push_back(&mut self, element: T) { pub fn push_back(&mut self, element: T) {
let element = Node::new(element).as_memref(); let element = Node::new(element).as_memref();
if let Some(tail) = self.tail.as_ref() { if let Some(tail) = self.tail.take() {
Node::get(tail).next = Some(element.clone()); Node::get(&tail).next = Some(element.clone());
Node::get(&element).prev = Some(tail.clone()); Node::get(&element).prev = Some(tail);
} } else {
if let None = self.tail.as_ref() {
self.head = Some(element.clone()); self.head = Some(element.clone());
} }
self.tail = Some(element.clone()); self.tail = Some(element);
self.size += 1; self.size += 1;
} }
pub fn pop_front(&mut self) -> Option<T> { pub fn pop_front(&mut self) -> Option<T> {
self.pop(true) self.get(0)
} }
pub fn pop_back(&mut self) -> Option<T> { pub fn pop_back(&mut self) -> Option<T> {
self.pop(false) self.get(-1)
}
fn pop(&mut self, from_head: bool) -> Option<T> {
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
} }
pub fn get(&mut self, n: i32) -> Option<T> { pub fn get(&mut self, n: i32) -> Option<T> {
if self.size == 0 {
return None;
}
let index = n + if n < 0 { self.size as i32 } else { 0 }; let index = n + if n < 0 { self.size as i32 } else { 0 };
if index == 0 { if let Some(node) = self.find(index) {
self.pop_front()
} else if (index - 1) as usize == self.size {
self.pop_back()
} else if let Some(node) = self.find(index) {
let mut node = Node::get(&node); let mut node = Node::get(&node);
let prev = node.prev.clone(); let prev = node.prev.clone();
let next = node.next.clone(); let next = node.next.clone();
@@ -201,18 +158,18 @@ impl<T> LinkedList<T> {
let from_head = index <= delta_back; let from_head = index <= delta_back;
let node = if from_head { &self.head } else { &self.tail }; let node = if from_head { &self.head } else { &self.tail };
let index = if from_head { index } else { delta_back }; let mut node = node.clone();
Self::find_node(node, index, from_head) let mut index = if from_head { index } else { delta_back };
while let Some(curr) = node {
if index == 0 {
return Some(curr.clone());
} }
fn find_node(node: &Pointer<Node<T>>, index: usize, from_head: bool) -> Pointer<Node<T>> {
if let Some(node) = node { let curr = curr.as_ref().borrow();
return if index == 0 { let curr = if from_head { &curr.next } else { &curr.prev };
Some(node.clone()) node = curr.clone();
} else { index -= 1;
let node = node.as_ref().borrow();
let node = if from_head { &node.next } else { &node.prev };
Self::find_node(node, index - 1, from_head)
};
} }
None None
} }

View File

@@ -3,4 +3,5 @@ pub mod es02_rational;
pub mod es04_rational_traits; pub mod es04_rational_traits;
pub mod es05_bank; pub mod es05_bank;
pub mod es06_list; pub mod es06_list;
pub mod es07_list_generic;
pub mod es08_folds; pub mod es08_folds;