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 insert(&mut self, value: T);
fn contains(&self, value: &T) -> bool; fn contains(&self, value: &T) -> bool;
fn remove(&mut self, value: &T); fn remove(&mut self, value: &T);
fn retrieve(&self, value: T) -> Option<&T>; fn retrieve(&self, value: &T) -> Option<&T>;
fn retrieve_as_mut(&mut self, value: T) -> Option<&mut T>; fn retrieve_as_mut(&mut self, value: &T) -> Option<&mut T>;
fn min(&self) -> Option<&T>; fn min(&self) -> Option<&T>;
fn max(&self) -> Option<&T>; fn max(&self) -> Option<&T>;
fn remove_min(&mut 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<(), ()> { fn iterative_insert(mut root: &mut HeapNode<T>, value: T) -> Result<(), ()> {
let mut current = root; while let Some(ref mut node) = root {
while let Some(ref mut node) = current {
match value.cmp(&node.value) { match value.cmp(&node.value) {
Ordering::Equal => return Err(()), Ordering::Equal => return Err(()),
Ordering::Less => current = &mut node.left, Ordering::Less => root = &mut node.left,
Ordering::Greater => current = &mut node.right, Ordering::Greater => root = &mut node.right,
} }
} }
*current = Some(Box::new(Node::new(value))); *root = Some(Box::new(Node::new(value)));
Ok(()) 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 { fn recursive_contains(&self, value: &T) -> bool {
match value.cmp(&self.value) { match value.cmp(&self.value) {
Ordering::Equal => true, 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) { match value.cmp(&self.value) {
Ordering::Equal => Some(&self.value), Ordering::Equal => Some(&self.value),
Ordering::Less => match self.left { 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) { match value.cmp(&self.value) {
Ordering::Equal => Some(&mut self.value), Ordering::Equal => Some(&mut self.value),
Ordering::Less => match self.left { 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<(), ()> { fn recursive_remove(root: &mut HeapNode<T>, value: &T) -> Result<(), ()> {
if let Some(ref mut node) = root { if let Some(ref mut node) = root {
return match value.cmp(&node.value) { return match value.cmp(&node.value) {
@ -279,6 +340,17 @@ impl<T: Ord> Node<T> {
Err(()) 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> { fn recursive_min(&self) -> Option<&T> {
match &self.left { match &self.left {
None => Some(&self.value), 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> { fn recursive_max(&self) -> Option<&T> {
match &self.right { match &self.right {
None => Some(&self.value), 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> { fn recursive_remove_min(root: &mut HeapNode<T>) -> Option<T> {
if root.as_ref().unwrap().left.is_some() { if root.as_ref().unwrap().left.is_some() {
Node::recursive_remove_min(&mut root.as_mut().unwrap().left) 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> { fn recursive_remove_max(root: &mut HeapNode<T>) -> Option<T> {
if root.as_ref().unwrap().right.is_some() { if root.as_ref().unwrap().right.is_some() {
Node::recursive_remove_max(&mut root.as_mut().unwrap().right) 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>) { fn recursive_consume_pre_order_vec(node: HeapNode<T>, elements: &mut Vec<T>) {
if let Some(node) = node { if let Some(node) = node {
elements.push(node.value); 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>) { fn recursive_consume_in_order_vec(node: HeapNode<T>, elements: &mut Vec<T>) {
if let Some(node) = node { if let Some(node) = node {
Node::recursive_consume_in_order_vec(node.left, elements); 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 { fn contains(&self, value: &T) -> bool {
match self.root { Node::iterative_contains(&self.root, value)
None => false,
Some(ref node) => node.recursive_contains(value),
}
} }
fn remove(&mut self, value: &T) { 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; self.size -= 1;
} }
} }
fn retrieve(&self, value: T) -> Option<&T> { fn retrieve(&self, value: &T) -> Option<&T> {
match self.root { Node::iterative_retrieve(&self.root, value)
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 { Node::iterative_retrieve_as_mut(&mut self.root, value)
None => None,
Some(ref mut node) => node.recursive_retrieve_as_mut(value),
}
} }
fn min(&self) -> Option<&T> { fn min(&self) -> Option<&T> {
match self.root { Node::iterative_min(&self.root)
None => None,
Some(ref node) => node.recursive_min(),
}
} }
fn max(&self) -> Option<&T> { fn max(&self) -> Option<&T> {
match self.root { Node::iterative_max(&self.root)
None => None,
Some(ref node) => node.recursive_max(),
}
} }
fn remove_min(&mut self) -> Option<T> { fn remove_min(&mut self) -> Option<T> {
let removed_min = match self.root { let removed_min = Node::iterative_remove_min(&mut self.root);
None => None,
Some(_) => Node::recursive_remove_min(&mut self.root),
};
if removed_min.is_some() { if removed_min.is_some() {
self.size -= 1; self.size -= 1;
} }
removed_min removed_min
} }
fn remove_max(&mut self) -> Option<T> { fn remove_max(&mut self) -> Option<T> {
let removed_max = match self.root { let removed_max = Node::iterative_remove_max(&mut self.root);
None => None,
Some(_) => Node::recursive_remove_max(&mut self.root),
};
if removed_max.is_some() { if removed_max.is_some() {
self.size -= 1; self.size -= 1;
} }
removed_max removed_max
} }
@ -567,9 +688,7 @@ impl<T: Ord> BinarySearchTree<T> for IterativeBST<T> {
} }
fn into_pre_order_iter(self) -> IntoIter<T> { fn into_pre_order_iter(self) -> IntoIter<T> {
let mut elements = Vec::new(); Node::iterative_consume_pre_order_vec(self.root).into_iter()
Node::recursive_consume_pre_order_vec(self.root, &mut elements);
elements.into_iter()
} }
fn into_in_order_iter(self) -> IntoIter<T> { 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 { match self.root {
None => None, None => None,
Some(ref node) => node.recursive_retrieve(value), 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 { match self.root {
None => None, None => None,
Some(ref mut node) => node.recursive_retrieve_as_mut(value), Some(ref mut node) => node.recursive_retrieve_as_mut(value),

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

@ -152,8 +152,8 @@ fn retrieve_element() {
bst.insert(5); bst.insert(5);
bst.insert(10); bst.insert(10);
let retrieved_value = bst.retrieve(5); let retrieved_value = bst.retrieve(&5);
let invalid_value = bst.retrieve(15); let invalid_value = bst.retrieve(&15);
assert_eq!(retrieved_value, Some(&5)); assert_eq!(retrieved_value, Some(&5));
assert_eq!(invalid_value, None); assert_eq!(invalid_value, None);
@ -169,7 +169,7 @@ fn retrieve_element_as_mut_and_modify_bst() {
actual_bst.insert(10); actual_bst.insert(10);
actual_bst.insert(5); 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; *_retrieved_value_as_mut = 2;
assert_eq!(actual_bst, expected_bst); assert_eq!(actual_bst, expected_bst);

Loading…
Cancel
Save