linked list push, push_first and get done!

This commit is contained in:
Víctor Martínez 2020-12-06 15:28:13 +01:00
parent 42e1b7e55d
commit 8c8b9e12ab
3 changed files with 117 additions and 27 deletions

View file

@ -1,20 +1,74 @@
pub use crate::models::linked_list::{Node, SharedNode};
use std::{cell::RefCell, rc::Rc};
use crate::models::linked_list::{Node, SharedNode};
pub struct DoublyLinkedList<T> {
length: u64,
root: Rc<RefCell<Node<T>>>,
root: SharedNode<T>,
}
impl<T> DoublyLinkedList<T> {
pub fn new() -> Self {
DoublyLinkedList {
length: 0,
root: Rc::new(RefCell::new(Node::new_head())),
root: Rc::new(RefCell::new(Some(Node {
elem: None,
next: Node::new_shared(None),
prev: Node::new_shared(None),
}))),
}
}
pub fn length(&self) -> u64 {
self.length
}
pub fn push(&mut self, value: T) {
let node = Node::new_shared(Some(value));
if self.length == 0 {
Node::set_next(&self.root, &node);
Node::set_prev(&node, &self.root);
} else {
let last = Node::get_prev(&self.root);
Node::set_next(&last, &node);
Node::set_prev(&node, &last);
}
Node::set_prev(&self.root, &node);
Node::set_next(&node, &self.root);
self.length += 1;
}
pub fn push_first(&mut self, value: T) {
let node = Node::new_shared(Some(value));
if self.length == 0 {
Node::set_prev(&self.root, &node);
Node::set_next(&node, &self.root);
} else {
let first = Node::get_next(&self.root);
Node::set_prev(&first, &node);
Node::set_next(&node, &first);
}
Node::set_next(&self.root, &node);
Node::set_prev(&node, &self.root);
self.length += 1;
}
pub fn get(&self, index: u64) -> SharedNode<T> {
if self.length == 0 || index >= self.length {
return Node::new_shared(None);
}
let mut current = Rc::clone(&self.root);
if index < self.length / 2 {
for _ in 0..index + 1 {
current = Node::get_next(&current);
}
} else {
for _ in 0..self.length - index {
current = Node::get_prev(&current);
}
}
current
}
}

View file

@ -4,42 +4,43 @@ pub type SharedNode<T> = Rc<RefCell<Option<Node<T>>>>;
#[allow(dead_code)]
pub struct Node<T> {
elem: Option<T>,
next: SharedNode<T>,
prev: SharedNode<T>,
pub elem: Option<T>,
pub next: SharedNode<T>,
pub prev: SharedNode<T>,
}
#[allow(dead_code)]
impl<T> Node<T> {
pub fn new(value: T, next: &SharedNode<T>, prev: &SharedNode<T>) -> Self {
Node {
elem: Some(value),
next: Rc::clone(next),
prev: Rc::clone(prev),
}
}
pub fn new_head() -> Self {
Node {
elem: None,
pub fn new_shared(value: Option<T>) -> SharedNode<T> {
Rc::new(RefCell::new(Some(Node {
elem: value,
next: Rc::new(RefCell::new(None)),
prev: Rc::new(RefCell::new(None)),
}
})))
}
pub fn is_none(node: &SharedNode<T>) -> bool {
node.borrow_mut().is_none()
}
pub fn elem(&self) -> Option<&T> {
self.elem.as_ref()
pub fn get_prev(node: &SharedNode<T>) -> SharedNode<T> {
Rc::clone(&(*node.borrow_mut()).as_mut().unwrap().prev)
}
pub fn elem_mut(&mut self) -> Option<&mut T> {
self.elem.as_mut()
pub fn get_next(node: &SharedNode<T>) -> SharedNode<T> {
Rc::clone(&(*node.borrow_mut()).as_mut().unwrap().next)
}
pub fn next(&self) -> SharedNode<T> {
Rc::clone(&self.next)
pub fn set_prev(node: &SharedNode<T>, to: &SharedNode<T>) {
let node = Rc::clone(node);
let ref mut node = *node.borrow_mut();
let node = node.as_mut().unwrap();
node.prev = Rc::clone(to);
}
pub fn prev(&self) -> SharedNode<T> {
Rc::clone(&self.prev)
pub fn set_next(node: &SharedNode<T>, to: &SharedNode<T>) {
let node = Rc::clone(node);
let ref mut node = *node.borrow_mut();
let node = node.as_mut().unwrap();
node.next = Rc::clone(to);
}
}

35
tests/linked_list_test.rs Normal file
View file

@ -0,0 +1,35 @@
use data_structs::linked_list::{DoublyLinkedList, SharedNode, Node};
fn get_elem(node: SharedNode<i32>) -> i32 {
let ref result = node.borrow();
let opt = result.as_ref().unwrap();
opt.elem.unwrap()
}
#[test]
fn test_push() {
let mut link_list: DoublyLinkedList<i32> = DoublyLinkedList::new();
link_list.push(3);
link_list.push(5);
let res1 = get_elem(link_list.get(0));
let res2 = get_elem(link_list.get(1));
assert_eq!(res1, 3);
assert_eq!(res2, 5);
}
#[test]
fn test_push_first() {
let mut link_list: DoublyLinkedList<i32> = DoublyLinkedList::new();
link_list.push_first(3);
link_list.push_first(5);
let res1 = get_elem(link_list.get(0));
let res2 = get_elem(link_list.get(1));
assert_eq!(res1, 5);
assert_eq!(res2, 3);
}