Updated Lists

This commit is contained in:
2024-06-01 16:19:35 +02:00
parent 23e9ac157f
commit 772ce302f4
2 changed files with 46 additions and 57 deletions

View File

@@ -38,9 +38,7 @@ impl<T:Copy> DoublyPointedList<T> {
} }
*/ */
use std::{ use std::{
cell::{RefCell, RefMut}, cell::{RefCell, RefMut}, fmt::Debug, mem, rc::Rc
fmt::Debug,
rc::Rc,
}; };
type Pointer<T> = Option<Rc<RefCell<T>>>; type Pointer<T> = Option<Rc<RefCell<T>>>;
@@ -53,8 +51,8 @@ pub struct LinkedList<T: Copy> {
struct Node<T: Copy> { struct Node<T: Copy> {
element: T, element: T,
next: Pointer<Node<T>>, next: Pointer<Self>,
prev: Pointer<Node<T>>, prev: Pointer<Self>,
} }
impl<T: Copy> Node<T> { impl<T: Copy> Node<T> {
@@ -65,9 +63,6 @@ impl<T: Copy> Node<T> {
prev: None, prev: None,
} }
} }
pub fn get(node: &Rc<RefCell<Node<T>>>) -> RefMut<Node<T>> {
node.as_ref().borrow_mut()
}
pub fn as_memref(self) -> Rc<RefCell<Node<T>>> { pub fn as_memref(self) -> Rc<RefCell<Node<T>>> {
Rc::new(RefCell::new(self)) Rc::new(RefCell::new(self))
} }
@@ -93,8 +88,8 @@ 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.take() { if let Some(head) = self.head.take() {
Node::get(&head).prev = Some(element.clone()); head.borrow_mut().prev = Some(element.clone());
Node::get(&element).next = Some(head); element.borrow_mut().next = Some(head);
} else { } else {
self.tail = Some(element.clone()); self.tail = Some(element.clone());
} }
@@ -105,8 +100,8 @@ impl<T: Copy> LinkedList<T> {
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.take() { if let Some(tail) = self.tail.take() {
Node::get(&tail).next = Some(element.clone()); tail.borrow_mut().next = Some(element.clone());
Node::get(&element).prev = Some(tail); element.borrow_mut().prev = Some(tail);
} else { } else {
self.head = Some(element.clone()); self.head = Some(element.clone());
} }
@@ -116,47 +111,46 @@ impl<T: Copy> LinkedList<T> {
} }
pub fn pop_front(&mut self) -> Option<T> { pub fn pop_front(&mut self) -> Option<T> {
if let Some(node) = self.head.take() { self.remove(0)
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> {
if let Some(node) = self.tail.take() { self.remove(-1)
let node = Node::get(&node); }
self.tail = node.prev.clone();
match self.tail.as_ref() { fn remove(&mut self, n: i32) -> Option<T> {
Some(other) => Node::get(other).next = None, let index = n + if n < 0 { self.size as i32 } else { 0 };
_ => self.head = None, if let Some(node) = self.find(index) {
let node = node.borrow_mut();
let prev = node.prev.clone();
let next = node.next.clone();
match &prev {
Some(val) => val.borrow_mut().next = next.clone(),
None => self.head = next.clone(),
}
match &next {
Some(val) => val.borrow_mut().prev = prev.clone(),
None => self.tail = prev.clone(),
} }
self.size -= 1; self.size -= 1;
return Some(node.element); Some(node.element)
} else {
None
} }
None
} }
pub fn get_front(&self) -> Option<T> { pub fn get_front(&self) -> Option<T> {
self.head.clone().and_then(|h| Some(Node::get(&h).element)) self.head.clone().and_then(|h| Some(h.borrow_mut().element))
} }
pub fn get_back(&self) -> Option<T> { pub fn get_back(&self) -> Option<T> {
self.tail.clone().and_then(|t| Some(Node::get(&t).element)) self.tail.clone().and_then(|t| Some(t.borrow_mut().element))
} }
pub fn get(&self, n: i32) -> Option<T> { pub fn get(&self, n: i32) -> Option<T> {
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) {
Some(Node::get(&node).element) Some(node.borrow_mut().element)
} else { } else {
None None
} }

View File

@@ -55,23 +55,20 @@ pub struct LinkedList<T> {
#[derive(Debug)] #[derive(Debug)]
struct Node<T> { struct Node<T> {
element: Option<T>, element: T,
next: Pointer<Node<T>>, next: Pointer<Self>,
prev: Pointer<Node<T>>, prev: Pointer<Self>,
} }
impl<T> Node<T> { impl<T> Node<T> {
pub fn new(element: T) -> Self { pub fn new(element: T) -> Self {
Self { Self {
element: Some(element), element,
next: None, next: None,
prev: None, prev: None,
} }
} }
pub fn get(node: &Rc<RefCell<Node<T>>>) -> RefMut<Node<T>> { pub fn as_memref(self) -> Rc<RefCell<Self>> {
node.as_ref().borrow_mut()
}
pub fn as_memref(self) -> Rc<RefCell<Node<T>>> {
Rc::new(RefCell::new(self)) Rc::new(RefCell::new(self))
} }
} }
@@ -96,8 +93,8 @@ 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.take() { if let Some(head) = self.head.take() {
Node::get(&head).prev = Some(element.clone()); head.borrow_mut().prev = Some(element.clone());
Node::get(&element).next = Some(head); element.borrow_mut().next = Some(head);
} else { } else {
self.tail = Some(element.clone()); self.tail = Some(element.clone());
} }
@@ -108,8 +105,8 @@ impl<T> LinkedList<T> {
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.take() { if let Some(tail) = self.tail.take() {
Node::get(&tail).next = Some(element.clone()); tail.borrow_mut().next = Some(element.clone());
Node::get(&element).prev = Some(tail); element.borrow_mut().prev = Some(tail);
} else { } else {
self.head = Some(element.clone()); self.head = Some(element.clone());
} }
@@ -128,24 +125,22 @@ impl<T> LinkedList<T> {
pub fn get(&mut self, n: i32) -> Option<T> { pub fn get(&mut self, n: i32) -> Option<T> {
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) {
let mut node = Node::get(&node); let temp = node.borrow_mut();
let prev = node.prev.clone(); let prev = temp.prev.clone();
let next = node.next.clone(); let next = temp.next.clone();
mem::drop(temp); // drop the borrow
match &prev { match &prev {
Some(val) => Node::get(val).next = next.clone(), Some(val) => val.borrow_mut().next = next.clone(),
None => self.head = next.clone(), None => self.head = next.clone(),
} }
match &next { match &next {
Some(val) => Node::get(val).prev = prev.clone(), Some(val) => val.borrow_mut().prev = prev.clone(),
None => self.tail = prev.clone(), None => self.tail = prev.clone(),
} }
self.size -= 1; self.size -= 1;
// Non avessi usato Option<T> avrei dovuto usare unsafe { mem::zeroed::<T>() } Some(Rc::try_unwrap(node).ok().unwrap().into_inner().element)
// ma siccome ha problemi con possibili implementazioni di T (vedasi Drop trait)
// ho scelto la via più safe anche se può occupare un byte in più di memoria
mem::take(&mut node.element)
} else { } else {
None None
} }