WIP Iterative implementation of BST

pull/3/head
sgoudham 3 years ago
parent 97e81f8620
commit bac301ad3a
Signed by: hammy
GPG Key ID: 44E818FD5457EEA4

@ -10,8 +10,8 @@ pub trait BinarySearchTree<T: Ord> {
fn insert(&mut self, value: T);
fn contains(&self, value: &T) -> bool;
fn remove(&mut self, value: &T);
fn retrieve(&self, value: T) -> Option<&T>;
fn retrieve_as_mut(&mut self, value: T) -> Option<&mut T>;
fn retrieve(&self, value: &T) -> Option<&T>;
fn retrieve_as_mut(&mut self, value: &T) -> Option<&mut T>;
fn min(&self) -> Option<&T>;
fn max(&self) -> Option<&T>;
fn remove_min(&mut self) -> Option<T>;
@ -179,17 +179,15 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_insert(root: &mut HeapNode<T>, value: T) -> Result<(), ()> {
let mut current = root;
while let Some(ref mut node) = current {
fn iterative_insert(mut root: &mut HeapNode<T>, value: T) -> Result<(), ()> {
while let Some(ref mut node) = root {
match value.cmp(&node.value) {
Ordering::Equal => return Err(()),
Ordering::Less => current = &mut node.left,
Ordering::Greater => current = &mut node.right,
Ordering::Less => root = &mut node.left,
Ordering::Greater => root = &mut node.right,
}
}
*current = Some(Box::new(Node::new(value)));
*root = Some(Box::new(Node::new(value)));
Ok(())
}
@ -214,6 +212,18 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_contains(mut root: &HeapNode<T>, value: &T) -> bool {
while let Some(current) = root {
match value.cmp(&current.value) {
Ordering::Equal => return true,
Ordering::Less => root = &current.left,
Ordering::Greater => root = &current.right,
}
}
false
}
fn recursive_contains(&self, value: &T) -> bool {
match value.cmp(&self.value) {
Ordering::Equal => true,
@ -228,7 +238,19 @@ impl<T: Ord> Node<T> {
}
}
fn recursive_retrieve(&self, value: T) -> Option<&T> {
fn iterative_retrieve<'a>(mut root: &'a HeapNode<T>, value: &T) -> Option<&'a T> {
while let Some(current) = root {
match value.cmp(&current.value) {
Ordering::Equal => return Some(&current.value),
Ordering::Less => root = &current.left,
Ordering::Greater => root = &current.right,
}
}
None
}
fn recursive_retrieve(&self, value: &T) -> Option<&T> {
match value.cmp(&self.value) {
Ordering::Equal => Some(&self.value),
Ordering::Less => match self.left {
@ -242,7 +264,22 @@ impl<T: Ord> Node<T> {
}
}
fn recursive_retrieve_as_mut(&mut self, value: T) -> Option<&mut T> {
fn iterative_retrieve_as_mut<'a>(
mut root: &'a mut HeapNode<T>,
value: &T,
) -> Option<&'a mut T> {
while let Some(current) = root {
match value.cmp(&current.value) {
Ordering::Equal => return Some(&mut current.value),
Ordering::Less => root = &mut current.left,
Ordering::Greater => root = &mut current.right,
}
}
None
}
fn recursive_retrieve_as_mut(&mut self, value: &T) -> Option<&mut T> {
match value.cmp(&self.value) {
Ordering::Equal => Some(&mut self.value),
Ordering::Less => match self.left {
@ -256,6 +293,30 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_remove(mut root: &mut HeapNode<T>, value: &T) -> Result<(), ()> {
while let Some(ref mut current) = root {
match value.cmp(&current.value) {
Ordering::Less => root = &mut root.as_mut().unwrap().left,
Ordering::Greater => root = &mut root.as_mut().unwrap().right,
Ordering::Equal => {
match (current.left.as_mut(), current.right.as_mut()) {
(None, None) => *root = None,
(Some(_), None) => *root = current.left.take(),
(None, Some(_)) => *root = current.right.take(),
(Some(_), Some(_)) => {
root.as_mut().unwrap().value =
Node::recursive_remove_min(&mut current.right).unwrap()
}
}
return Ok(());
}
}
}
Err(())
}
fn recursive_remove(root: &mut HeapNode<T>, value: &T) -> Result<(), ()> {
if let Some(ref mut node) = root {
return match value.cmp(&node.value) {
@ -279,6 +340,17 @@ impl<T: Ord> Node<T> {
Err(())
}
fn iterative_min(mut root: &HeapNode<T>) -> Option<&T> {
while let Some(current) = root {
if current.left.is_none() {
return Some(&current.value);
}
root = &current.left;
}
None
}
fn recursive_min(&self) -> Option<&T> {
match &self.left {
None => Some(&self.value),
@ -286,6 +358,17 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_max(mut root: &HeapNode<T>) -> Option<&T> {
while let Some(current) = root {
if current.right.is_none() {
return Some(&current.value);
}
root = &current.right;
}
None
}
fn recursive_max(&self) -> Option<&T> {
match &self.right {
None => Some(&self.value),
@ -293,6 +376,20 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_remove_min(mut root: &mut HeapNode<T>) -> Option<T> {
if root.is_some() {
while root.as_ref().unwrap().left.is_some() {
root = &mut root.as_mut().unwrap().left
}
let node = root.take().unwrap();
*root = node.right;
return Some(node.value);
}
None
}
fn recursive_remove_min(root: &mut HeapNode<T>) -> Option<T> {
if root.as_ref().unwrap().left.is_some() {
Node::recursive_remove_min(&mut root.as_mut().unwrap().left)
@ -303,6 +400,20 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_remove_max(mut root: &mut HeapNode<T>) -> Option<T> {
if root.is_some() {
while root.as_ref().unwrap().right.is_some() {
root = &mut root.as_mut().unwrap().right
}
let node = root.take().unwrap();
*root = node.left;
return Some(node.value);
}
None
}
fn recursive_remove_max(root: &mut HeapNode<T>) -> Option<T> {
if root.as_ref().unwrap().right.is_some() {
Node::recursive_remove_max(&mut root.as_mut().unwrap().right)
@ -411,6 +522,23 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_consume_pre_order_vec(node: HeapNode<T>) -> Vec<T> {
let mut elements = Vec::new();
let mut stack = vec![node];
while let Some(current) = stack.pop().unwrap_or(None) {
elements.push(current.value);
if current.right.is_some() {
stack.push(current.right);
}
if current.left.is_some() {
stack.push(current.left);
}
}
elements
}
fn recursive_consume_pre_order_vec(node: HeapNode<T>, elements: &mut Vec<T>) {
if let Some(node) = node {
elements.push(node.value);
@ -419,6 +547,24 @@ impl<T: Ord> Node<T> {
}
}
fn iterative_consume_in_order_vec(mut root: HeapNode<T>) -> Vec<T> {
let mut elements = Vec::new();
let mut stack = Vec::new();
while !stack.is_empty() || root.is_some() {
if root.is_some() {
stack.push(root.as_ref().unwrap());
root = root.unwrap().left;
} else {
let node = stack.pop();
elements.push(node.as_ref().unwrap().value);
root = node.as_ref().unwrap().right;
}
}
elements
}
fn recursive_consume_in_order_vec(node: HeapNode<T>, elements: &mut Vec<T>) {
if let Some(node) = node {
Node::recursive_consume_in_order_vec(node.left, elements);
@ -466,69 +612,44 @@ impl<T: Ord> BinarySearchTree<T> for IterativeBST<T> {
}
fn contains(&self, value: &T) -> bool {
match self.root {
None => false,
Some(ref node) => node.recursive_contains(value),
}
Node::iterative_contains(&self.root, value)
}
fn remove(&mut self, value: &T) {
if Node::recursive_remove(&mut self.root, value).is_ok() {
if Node::iterative_remove(&mut self.root, value).is_ok() {
self.size -= 1;
}
}
fn retrieve(&self, value: T) -> Option<&T> {
match self.root {
None => None,
Some(ref node) => node.recursive_retrieve(value),
}
fn retrieve(&self, value: &T) -> Option<&T> {
Node::iterative_retrieve(&self.root, value)
}
fn retrieve_as_mut(&mut self, value: T) -> Option<&mut T> {
match self.root {
None => None,
Some(ref mut node) => node.recursive_retrieve_as_mut(value),
}
fn retrieve_as_mut(&mut self, value: &T) -> Option<&mut T> {
Node::iterative_retrieve_as_mut(&mut self.root, value)
}
fn min(&self) -> Option<&T> {
match self.root {
None => None,
Some(ref node) => node.recursive_min(),
}
Node::iterative_min(&self.root)
}
fn max(&self) -> Option<&T> {
match self.root {
None => None,
Some(ref node) => node.recursive_max(),
}
Node::iterative_max(&self.root)
}
fn remove_min(&mut self) -> Option<T> {
let removed_min = match self.root {
None => None,
Some(_) => Node::recursive_remove_min(&mut self.root),
};
let removed_min = Node::iterative_remove_min(&mut self.root);
if removed_min.is_some() {
self.size -= 1;
}
removed_min
}
fn remove_max(&mut self) -> Option<T> {
let removed_max = match self.root {
None => None,
Some(_) => Node::recursive_remove_max(&mut self.root),
};
let removed_max = Node::iterative_remove_max(&mut self.root);
if removed_max.is_some() {
self.size -= 1;
}
removed_max
}
@ -567,9 +688,7 @@ impl<T: Ord> BinarySearchTree<T> for IterativeBST<T> {
}
fn into_pre_order_iter(self) -> IntoIter<T> {
let mut elements = Vec::new();
Node::recursive_consume_pre_order_vec(self.root, &mut elements);
elements.into_iter()
Node::iterative_consume_pre_order_vec(self.root).into_iter()
}
fn into_in_order_iter(self) -> IntoIter<T> {
@ -635,14 +754,14 @@ impl<T: Ord> BinarySearchTree<T> for RecursiveBST<T> {
}
}
fn retrieve(&self, value: T) -> Option<&T> {
fn retrieve(&self, value: &T) -> Option<&T> {
match self.root {
None => None,
Some(ref node) => node.recursive_retrieve(value),
}
}
fn retrieve_as_mut(&mut self, value: T) -> Option<&mut T> {
fn retrieve_as_mut(&mut self, value: &T) -> Option<&mut T> {
match self.root {
None => None,
Some(ref mut node) => node.recursive_retrieve_as_mut(value),

@ -1,7 +1,9 @@
use std::vec::IntoIter;
use bst_rs::{BinarySearchTree, IterativeBST};
#[test]
fn can_insert_element() {
fn successfully_insert_elements_into_bst() {
let mut expected_bst = IterativeBST::empty();
expected_bst.insert(-1);
expected_bst.insert(0);
@ -17,6 +19,7 @@ fn can_insert_element() {
actual_bst.insert(-20);
assert_eq!(actual_bst, expected_bst);
assert_eq!(actual_bst.size(), 5);
}
#[test]
@ -29,8 +32,9 @@ fn check_if_bst_is_empty() {
}
#[test]
fn check_element_exists() {
fn check_if_bst_contains_elements() {
let mut bst = IterativeBST::empty();
assert!(!bst.contains(&10));
bst.insert(1);
bst.insert(5);
@ -41,13 +45,10 @@ fn check_element_exists() {
}
#[test]
fn remove_root_element() {
fn successfully_remove_root_node_from_bst() {
let mut bst = IterativeBST::empty();
bst.insert(0);
assert!(!bst.is_empty());
assert_eq!(bst.size(), 1);
bst.remove(&0);
assert!(bst.is_empty());
@ -55,7 +56,7 @@ fn remove_root_element() {
}
#[test]
fn remove_leaf_node() {
fn successfully_remove_leaf_node() {
let mut expected_bst = IterativeBST::empty();
expected_bst.insert(5);
expected_bst.insert(4);
@ -88,6 +89,7 @@ fn remove_single_right_node_with_children() {
actual_bst.remove(&6);
println!("{}", actual_bst);
assert_eq!(actual_bst.size(), 4);
assert_eq!(actual_bst, expected_bst);
}
@ -159,8 +161,8 @@ fn retrieve_element() {
bst.insert(5);
bst.insert(10);
let retrieved_value = bst.retrieve(5);
let invalid_value = bst.retrieve(15);
let retrieved_value = bst.retrieve(&5);
let invalid_value = bst.retrieve(&15);
assert_eq!(retrieved_value, Some(&5));
assert_eq!(invalid_value, None);
@ -176,7 +178,7 @@ fn retrieve_element_as_mut_and_modify_bst() {
actual_bst.insert(10);
actual_bst.insert(5);
let _retrieved_value_as_mut: &mut i32 = actual_bst.retrieve_as_mut(5).unwrap();
let _retrieved_value_as_mut: &mut i32 = actual_bst.retrieve_as_mut(&5).unwrap();
*_retrieved_value_as_mut = 2;
assert_eq!(actual_bst, expected_bst);
@ -342,6 +344,9 @@ fn post_order_iter() {
#[test]
fn into_pre_order_iter() {
let mut iter: IntoIter<i32> = IterativeBST::empty().into_pre_order_iter();
assert_eq!(iter.next(), None);
let mut bst = IterativeBST::empty();
bst.insert(3);
bst.insert(4);

@ -152,8 +152,8 @@ fn retrieve_element() {
bst.insert(5);
bst.insert(10);
let retrieved_value = bst.retrieve(5);
let invalid_value = bst.retrieve(15);
let retrieved_value = bst.retrieve(&5);
let invalid_value = bst.retrieve(&15);
assert_eq!(retrieved_value, Some(&5));
assert_eq!(invalid_value, None);
@ -169,7 +169,7 @@ fn retrieve_element_as_mut_and_modify_bst() {
actual_bst.insert(10);
actual_bst.insert(5);
let _retrieved_value_as_mut: &mut i32 = actual_bst.retrieve_as_mut(5).unwrap();
let _retrieved_value_as_mut: &mut i32 = actual_bst.retrieve_as_mut(&5).unwrap();
*_retrieved_value_as_mut = 2;
assert_eq!(actual_bst, expected_bst);

Loading…
Cancel
Save