Updated Lists
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user