mirror of
https://codeberg.org/JasterV/cool-data-structures.git
synced 2026-04-26 18:40:04 +00:00
linked list remove action tested
This commit is contained in:
parent
8c8b9e12ab
commit
6adebe2d69
3 changed files with 120 additions and 63 deletions
|
|
@ -1,4 +1,4 @@
|
|||
pub use crate::models::linked_list::{Node, SharedNode};
|
||||
use crate::models::linked_list::{Node, SharedNode};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct DoublyLinkedList<T> {
|
||||
|
|
@ -10,11 +10,11 @@ impl<T> DoublyLinkedList<T> {
|
|||
pub fn new() -> Self {
|
||||
DoublyLinkedList {
|
||||
length: 0,
|
||||
root: Rc::new(RefCell::new(Some(Node {
|
||||
root: Rc::new(RefCell::new(Node {
|
||||
elem: None,
|
||||
next: Node::new_shared(None),
|
||||
prev: Node::new_shared(None),
|
||||
}))),
|
||||
next: None,
|
||||
prev: None,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,49 +26,70 @@ impl<T> DoublyLinkedList<T> {
|
|||
let node = Node::new_shared(Some(value));
|
||||
|
||||
if self.length == 0 {
|
||||
Node::set_next(&self.root, &node);
|
||||
Node::set_prev(&node, &self.root);
|
||||
Node::set_next(&self.root, Some(&node));
|
||||
Node::set_prev(&node, Some(&self.root));
|
||||
} else {
|
||||
let last = Node::get_prev(&self.root);
|
||||
Node::set_next(&last, &node);
|
||||
Node::set_prev(&node, &last);
|
||||
let last = Node::get_prev(&self.root).unwrap();
|
||||
Node::set_next(&last, Some(&node));
|
||||
Node::set_prev(&node, Some(&last));
|
||||
}
|
||||
Node::set_prev(&self.root, &node);
|
||||
Node::set_next(&node, &self.root);
|
||||
Node::set_prev(&self.root, Some(&node));
|
||||
Node::set_next(&node, Some(&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);
|
||||
Node::set_prev(&self.root, Some(&node));
|
||||
Node::set_next(&node, Some(&self.root));
|
||||
} else {
|
||||
let first = Node::get_next(&self.root);
|
||||
Node::set_prev(&first, &node);
|
||||
Node::set_next(&node, &first);
|
||||
let first = Node::get_next(&self.root).unwrap();
|
||||
Node::set_prev(&first, Some(&node));
|
||||
Node::set_next(&node, Some(&first));
|
||||
}
|
||||
Node::set_next(&self.root, &node);
|
||||
Node::set_prev(&node, &self.root);
|
||||
Node::set_next(&self.root, Some(&node));
|
||||
Node::set_prev(&node, Some(&self.root));
|
||||
self.length += 1;
|
||||
}
|
||||
|
||||
pub fn get(&self, index: u64) -> SharedNode<T> {
|
||||
pub fn get(&self, index: u64) -> Option<Rc<RefCell<T>>> {
|
||||
self._get_node(index).and_then(|rc| Node::get_elem(&rc))
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: u64) -> Result<(), String> {
|
||||
let node = self._get_node(index).ok_or(String::from("Invalid index"))?;
|
||||
|
||||
let prev = Node::get_prev(&node).unwrap();
|
||||
let next = Node::get_next(&node).unwrap();
|
||||
|
||||
Node::set_next(&prev, Some(&next));
|
||||
Node::set_prev(&next, Some(&prev));
|
||||
|
||||
if self.length == 1 {
|
||||
Node::set_next(&self.root, None);
|
||||
Node::set_prev(&self.root, None);
|
||||
}
|
||||
self.length -= 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _get_node(&self, index: u64) -> Option<SharedNode<T>> {
|
||||
if self.length == 0 || index >= self.length {
|
||||
return Node::new_shared(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut current = Rc::clone(&self.root);
|
||||
if index < self.length / 2 {
|
||||
for _ in 0..index + 1 {
|
||||
current = Node::get_next(¤t);
|
||||
current = Node::get_next(¤t).unwrap();
|
||||
}
|
||||
} else {
|
||||
for _ in 0..self.length - index {
|
||||
current = Node::get_prev(¤t);
|
||||
current = Node::get_prev(¤t).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
current
|
||||
Some(Rc::clone(¤t))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +1,50 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub type SharedNode<T> = Rc<RefCell<Option<Node<T>>>>;
|
||||
pub type SharedNode<T> = Rc<RefCell<Node<T>>>;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Node<T> {
|
||||
pub elem: Option<T>,
|
||||
pub next: SharedNode<T>,
|
||||
pub prev: SharedNode<T>,
|
||||
pub elem: Option<Rc<RefCell<T>>>,
|
||||
pub next: Option<SharedNode<T>>,
|
||||
pub prev: Option<SharedNode<T>>,
|
||||
}
|
||||
|
||||
impl<T> Node<T> {
|
||||
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()
|
||||
Rc::new(RefCell::new(Node {
|
||||
elem: value.map(|elem| Rc::new(RefCell::new(elem))),
|
||||
next: None,
|
||||
prev: None,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn get_prev(node: &SharedNode<T>) -> SharedNode<T> {
|
||||
Rc::clone(&(*node.borrow_mut()).as_mut().unwrap().prev)
|
||||
pub fn get_elem(node: &SharedNode<T>) -> Option<Rc<RefCell<T>>> {
|
||||
let node = node.borrow();
|
||||
match &node.elem {
|
||||
Some(rc) => Some(Rc::clone(&rc)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_next(node: &SharedNode<T>) -> SharedNode<T> {
|
||||
Rc::clone(&(*node.borrow_mut()).as_mut().unwrap().next)
|
||||
pub fn get_prev(node: &SharedNode<T>) -> Option<SharedNode<T>> {
|
||||
let ref mut node = *node.borrow_mut();
|
||||
node.prev.as_ref().and_then(|prev| Some(Rc::clone(prev)))
|
||||
}
|
||||
|
||||
pub fn set_prev(node: &SharedNode<T>, to: &SharedNode<T>) {
|
||||
pub fn get_next(node: &SharedNode<T>) -> Option<SharedNode<T>> {
|
||||
let ref mut node = *node.borrow_mut();
|
||||
node.next.as_ref().and_then(|next| Some(Rc::clone(next)))
|
||||
}
|
||||
|
||||
pub fn set_prev(node: &SharedNode<T>, to: Option<&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);
|
||||
node.prev = to.map(|rc| Rc::clone(rc));
|
||||
}
|
||||
|
||||
pub fn set_next(node: &SharedNode<T>, to: &SharedNode<T>) {
|
||||
pub fn set_next(node: &SharedNode<T>, to: Option<&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);
|
||||
node.next = to.map(|rc| Rc::clone(rc));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
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()
|
||||
}
|
||||
use data_structs::linked_list::DoublyLinkedList;
|
||||
|
||||
#[test]
|
||||
fn test_push() {
|
||||
|
|
@ -13,11 +6,11 @@ fn test_push() {
|
|||
link_list.push(3);
|
||||
link_list.push(5);
|
||||
|
||||
let res1 = get_elem(link_list.get(0));
|
||||
let res2 = get_elem(link_list.get(1));
|
||||
let res1 = link_list.get(0).unwrap();
|
||||
let res2 = link_list.get(1).unwrap();
|
||||
|
||||
assert_eq!(res1, 3);
|
||||
assert_eq!(res2, 5);
|
||||
assert_eq!(*res1.borrow(), 3);
|
||||
assert_eq!(*res2.borrow(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -26,10 +19,49 @@ fn test_push_first() {
|
|||
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));
|
||||
let res1 = link_list.get(0).unwrap();
|
||||
let res2 = link_list.get(1).unwrap();
|
||||
|
||||
assert_eq!(res1, 5);
|
||||
assert_eq!(res2, 3);
|
||||
assert_eq!(*res1.borrow(), 5);
|
||||
assert_eq!(*res2.borrow(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combine_push() {
|
||||
let mut link_list: DoublyLinkedList<i32> = DoublyLinkedList::new();
|
||||
link_list.push(3);
|
||||
link_list.push_first(23);
|
||||
link_list.push(10);
|
||||
link_list.push_first(5);
|
||||
|
||||
let res1 = link_list.get(0).unwrap();
|
||||
let res2 = link_list.get(1).unwrap();
|
||||
let res3 = link_list.get(2).unwrap();
|
||||
let res4 = link_list.get(3).unwrap();
|
||||
let res5 = link_list.get(4);
|
||||
|
||||
assert_eq!(*res1.borrow(), 5);
|
||||
assert_eq!(*res2.borrow(), 23);
|
||||
assert_eq!(*res3.borrow(), 3);
|
||||
assert_eq!(*res4.borrow(), 10);
|
||||
assert!(res5.is_none());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_remove() {
|
||||
let mut link_list: DoublyLinkedList<i32> = DoublyLinkedList::new();
|
||||
link_list.push(3);
|
||||
link_list.push(10);
|
||||
link_list.push(40);
|
||||
|
||||
assert_eq!(link_list.length(), 3);
|
||||
|
||||
link_list.remove(2).unwrap();
|
||||
|
||||
assert_eq!(link_list.length(), 2);
|
||||
let n = link_list.get(1).unwrap();
|
||||
assert_eq!(*n.borrow(), 10);
|
||||
assert!(link_list.get(2).is_none());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue