mirror of
https://codeberg.org/JasterV/cool-data-structures.git
synced 2026-04-26 18:40:04 +00:00
linked list push, push_first and get done!
This commit is contained in:
parent
42e1b7e55d
commit
8c8b9e12ab
3 changed files with 117 additions and 27 deletions
|
|
@ -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(¤t);
|
||||
}
|
||||
} else {
|
||||
for _ in 0..self.length - index {
|
||||
current = Node::get_prev(¤t);
|
||||
}
|
||||
}
|
||||
|
||||
current
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
35
tests/linked_list_test.rs
Normal 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);
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue