Binary Tree implemented, traversals implemented, tests done

This commit is contained in:
Víctor Martínez 2020-12-07 02:33:31 +01:00
parent 7632769608
commit a32b04a451
6 changed files with 201 additions and 4 deletions

71
src/binary_tree.rs Normal file
View file

@ -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<T> {
root: Option<Box<Node<T>>>,
}
impl<T: PartialOrd> BinaryTree<T> {
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<Rc<RefCell<T>>> {
Self::_inorder(self.root.as_ref())
}
pub fn postorder(&self) -> Vec<Rc<RefCell<T>>> {
Self::_postorder(self.root.as_ref())
}
pub fn preorder(&self) -> Vec<Rc<RefCell<T>>> {
Self::_preorder(self.root.as_ref())
}
fn _inorder(node: Option<&Box<Node<T>>>) -> Vec<Rc<RefCell<T>>> {
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<Node<T>>>) -> Vec<Rc<RefCell<T>>> {
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<Node<T>>>) -> Vec<Rc<RefCell<T>>> {
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
}
}

View file

@ -1,3 +1,4 @@
mod models;
pub mod linked_list;
pub mod linked_list;
pub mod binary_tree;

View file

@ -57,15 +57,22 @@ impl<T> DoublyLinkedList<T> {
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);

55
src/models/binary_tree.rs Normal file
View file

@ -0,0 +1,55 @@
use std::boxed::Box;
use std::cell::RefCell;
use std::rc::Rc;
pub struct Node<T> {
elem: Rc<RefCell<T>>,
pub left: Option<Box<Node<T>>>,
pub right: Option<Box<Node<T>>>,
}
impl<T: PartialOrd> Node<T> {
pub fn new(value: T) -> Self {
Node {
elem: Rc::new(RefCell::new(value)),
left: None,
right: None,
}
}
pub fn elem(&self) -> Rc<RefCell<T>> {
Rc::clone(&self.elem)
}
pub fn left(&self) -> Option<&Box<Node<T>>> {
self.left.as_ref()
}
pub fn right(&self) -> Option<&Box<Node<T>>> {
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))),
}
}
}
}

View file

@ -1 +1,2 @@
pub mod linked_list;
pub mod linked_list;
pub mod binary_tree;

62
tests/binary_tree.rs Normal file
View file

@ -0,0 +1,62 @@
use data_structs::binary_tree::BinaryTree;
#[test]
fn test_insert() {
let mut btree: BinaryTree<i32> = 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<i32> = 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<i32> = 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<i32> = 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);
}