From a32b04a451d8c89b03d7d8da62ec8491758b224b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Mon, 7 Dec 2020 02:33:31 +0100 Subject: [PATCH] Binary Tree implemented, traversals implemented, tests done --- src/binary_tree.rs | 71 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +- src/linked_list.rs | 11 ++++-- src/models/binary_tree.rs | 55 ++++++++++++++++++++++++++++++ src/models/mod.rs | 3 +- tests/binary_tree.rs | 62 ++++++++++++++++++++++++++++++++++ 6 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 src/binary_tree.rs create mode 100644 src/models/binary_tree.rs create mode 100644 tests/binary_tree.rs diff --git a/src/binary_tree.rs b/src/binary_tree.rs new file mode 100644 index 0000000..a0c1188 --- /dev/null +++ b/src/binary_tree.rs @@ -0,0 +1,71 @@ +use std::boxed::Box; +use std::rc::Rc; +use std::{cell::RefCell, vec}; + +use crate::models::binary_tree::Node; + +pub struct BinaryTree { + root: Option>>, +} + +impl BinaryTree { + pub fn new() -> Self { + BinaryTree { root: None } + } + + pub fn size(&self) -> u32 { + match self.root { + Some(ref node) => node.size(), + _ => 0, + } + } + + pub fn insert(&mut self, value: T) { + match self.root { + Some(ref mut elem) => elem.insert(value), + _ => self.root = Some(Box::new(Node::new(value))), + } + } + + pub fn inorder(&self) -> Vec>> { + Self::_inorder(self.root.as_ref()) + } + + pub fn postorder(&self) -> Vec>> { + Self::_postorder(self.root.as_ref()) + } + + pub fn preorder(&self) -> Vec>> { + Self::_preorder(self.root.as_ref()) + } + + fn _inorder(node: Option<&Box>>) -> Vec>> { + let mut result = Vec::new(); + if let Some(ref node) = node { + result.append(&mut Self::_inorder(node.left())); + result.append(&mut vec![node.elem()]); + result.append(&mut Self::_inorder(node.right())); + }; + result + } + + fn _postorder(node: Option<&Box>>) -> Vec>> { + let mut result = Vec::new(); + if let Some(ref node) = node { + result.append(&mut Self::_postorder(node.left())); + result.append(&mut Self::_postorder(node.right())); + result.append(&mut vec![node.elem()]) + }; + result + } + + fn _preorder(node: Option<&Box>>) -> Vec>> { + let mut result = Vec::new(); + if let Some(ref node) = node { + result.append(&mut vec![node.elem()]); + result.append(&mut Self::_preorder(node.left())); + result.append(&mut Self::_preorder(node.right())); + }; + result + } +} diff --git a/src/lib.rs b/src/lib.rs index a753b92..dbbd00a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ mod models; -pub mod linked_list; \ No newline at end of file +pub mod linked_list; +pub mod binary_tree; \ No newline at end of file diff --git a/src/linked_list.rs b/src/linked_list.rs index 8347e1b..33eb10e 100644 --- a/src/linked_list.rs +++ b/src/linked_list.rs @@ -57,15 +57,22 @@ impl DoublyLinkedList { self._get_node(index).and_then(|rc| Node::get_elem(&rc)) } + pub fn set(&self, index: u64, value: T) { + let elem = self._get_node(index) + .and_then(|rc| Node::get_elem(&rc)) + .expect("Index out of bounds"); + *elem.borrow_mut() = value; + } + 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); diff --git a/src/models/binary_tree.rs b/src/models/binary_tree.rs new file mode 100644 index 0000000..60a69d5 --- /dev/null +++ b/src/models/binary_tree.rs @@ -0,0 +1,55 @@ +use std::boxed::Box; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct Node { + elem: Rc>, + pub left: Option>>, + pub right: Option>>, +} + +impl Node { + pub fn new(value: T) -> Self { + Node { + elem: Rc::new(RefCell::new(value)), + left: None, + right: None, + } + } + + pub fn elem(&self) -> Rc> { + Rc::clone(&self.elem) + } + + pub fn left(&self) -> Option<&Box>> { + self.left.as_ref() + } + + pub fn right(&self) -> Option<&Box>> { + self.right.as_ref() + } + + pub fn size(&self) -> u32 { + 1 + match self.left { + Some(ref elem) => elem.size(), + _ => 0, + } + match self.right { + Some(ref elem) => elem.size(), + _ => 0, + } + } + + pub fn insert(&mut self, value: T) { + if value <= *self.elem.borrow() { + match self.left { + Some(ref mut elem) => elem.insert(value), + None => self.left = Some(Box::new(Node::new(value))), + } + } else { + match self.right { + Some(ref mut elem) => elem.insert(value), + None => self.right = Some(Box::new(Node::new(value))), + } + } + } +} \ No newline at end of file diff --git a/src/models/mod.rs b/src/models/mod.rs index 9693789..f0d2854 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1 +1,2 @@ -pub mod linked_list; \ No newline at end of file +pub mod linked_list; +pub mod binary_tree; \ No newline at end of file diff --git a/tests/binary_tree.rs b/tests/binary_tree.rs new file mode 100644 index 0000000..d6e7784 --- /dev/null +++ b/tests/binary_tree.rs @@ -0,0 +1,62 @@ +use data_structs::binary_tree::BinaryTree; + +#[test] +fn test_insert() { + let mut btree: BinaryTree = BinaryTree::new(); + + btree.insert(10); + btree.insert(8); + btree.insert(11); + btree.insert(7); + + assert_eq!(btree.size(), 4); +} +#[test] +fn test_inorder() { + let mut btree: BinaryTree = BinaryTree::new(); + + btree.insert(10); + btree.insert(8); + btree.insert(11); + btree.insert(7); + + let inorder = btree.inorder(); + + assert_eq!(inorder.len(), 4); + assert_eq!(*inorder[0].borrow(), 7); + assert_eq!(*inorder[3].borrow(), 11); +} + +#[test] +fn test_postorder() { + let mut btree: BinaryTree = BinaryTree::new(); + + btree.insert(10); + btree.insert(8); + btree.insert(11); + btree.insert(7); + + let inorder = btree.inorder(); + + assert_eq!(inorder.len(), 4); + assert_eq!(*inorder[0].borrow(), 7); + assert_eq!(*inorder[3].borrow(), 11); +} + +#[test] +fn test_preorder() { + let mut btree: BinaryTree = BinaryTree::new(); + + btree.insert(10); + btree.insert(8); + btree.insert(11); + btree.insert(7); + + let preorder = btree.preorder(); + + assert_eq!(preorder.len(), 4); + assert_eq!(*preorder[0].borrow(), 10); + assert_eq!(*preorder[3].borrow(), 11); + assert_eq!(*preorder[2].borrow(), 7); +} +