From bac301ad3a2831b07f4b32a6214a3b1dc53b1c4d Mon Sep 17 00:00:00 2001 From: sgoudham Date: Sat, 19 Feb 2022 16:14:35 +0000 Subject: [PATCH] WIP Iterative implementation of BST --- src/lib.rs | 221 +++++++++++++++++++++++++++++++---------- tests/iterative_bst.rs | 25 +++-- tests/recursive_bst.rs | 6 +- 3 files changed, 188 insertions(+), 64 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3ef853d..9a1d81b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,8 +10,8 @@ pub trait BinarySearchTree { 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; @@ -179,17 +179,15 @@ impl Node { } } - fn iterative_insert(root: &mut HeapNode, value: T) -> Result<(), ()> { - let mut current = root; - - while let Some(ref mut node) = current { + fn iterative_insert(mut root: &mut HeapNode, 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 Node { } } + fn iterative_contains(mut root: &HeapNode, value: &T) -> bool { + while let Some(current) = root { + match value.cmp(¤t.value) { + Ordering::Equal => return true, + Ordering::Less => root = ¤t.left, + Ordering::Greater => root = ¤t.right, + } + } + + false + } + fn recursive_contains(&self, value: &T) -> bool { match value.cmp(&self.value) { Ordering::Equal => true, @@ -228,7 +238,19 @@ impl Node { } } - fn recursive_retrieve(&self, value: T) -> Option<&T> { + fn iterative_retrieve<'a>(mut root: &'a HeapNode, value: &T) -> Option<&'a T> { + while let Some(current) = root { + match value.cmp(¤t.value) { + Ordering::Equal => return Some(¤t.value), + Ordering::Less => root = ¤t.left, + Ordering::Greater => root = ¤t.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 Node { } } - fn recursive_retrieve_as_mut(&mut self, value: T) -> Option<&mut T> { + fn iterative_retrieve_as_mut<'a>( + mut root: &'a mut HeapNode, + value: &T, + ) -> Option<&'a mut T> { + while let Some(current) = root { + match value.cmp(¤t.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 Node { } } + fn iterative_remove(mut root: &mut HeapNode, value: &T) -> Result<(), ()> { + while let Some(ref mut current) = root { + match value.cmp(¤t.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, value: &T) -> Result<(), ()> { if let Some(ref mut node) = root { return match value.cmp(&node.value) { @@ -279,6 +340,17 @@ impl Node { Err(()) } + fn iterative_min(mut root: &HeapNode) -> Option<&T> { + while let Some(current) = root { + if current.left.is_none() { + return Some(¤t.value); + } + root = ¤t.left; + } + + None + } + fn recursive_min(&self) -> Option<&T> { match &self.left { None => Some(&self.value), @@ -286,6 +358,17 @@ impl Node { } } + fn iterative_max(mut root: &HeapNode) -> Option<&T> { + while let Some(current) = root { + if current.right.is_none() { + return Some(¤t.value); + } + root = ¤t.right; + } + + None + } + fn recursive_max(&self) -> Option<&T> { match &self.right { None => Some(&self.value), @@ -293,6 +376,20 @@ impl Node { } } + fn iterative_remove_min(mut root: &mut HeapNode) -> Option { + 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) -> Option { if root.as_ref().unwrap().left.is_some() { Node::recursive_remove_min(&mut root.as_mut().unwrap().left) @@ -303,6 +400,20 @@ impl Node { } } + fn iterative_remove_max(mut root: &mut HeapNode) -> Option { + 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) -> Option { if root.as_ref().unwrap().right.is_some() { Node::recursive_remove_max(&mut root.as_mut().unwrap().right) @@ -411,6 +522,23 @@ impl Node { } } + fn iterative_consume_pre_order_vec(node: HeapNode) -> Vec { + 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, elements: &mut Vec) { if let Some(node) = node { elements.push(node.value); @@ -419,6 +547,24 @@ impl Node { } } + fn iterative_consume_in_order_vec(mut root: HeapNode) -> Vec { + 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, elements: &mut Vec) { if let Some(node) = node { Node::recursive_consume_in_order_vec(node.left, elements); @@ -466,69 +612,44 @@ impl BinarySearchTree for IterativeBST { } 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 { - 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 { - 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 BinarySearchTree for IterativeBST { } fn into_pre_order_iter(self) -> IntoIter { - 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 { @@ -635,14 +754,14 @@ impl BinarySearchTree for RecursiveBST { } } - 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), diff --git a/tests/iterative_bst.rs b/tests/iterative_bst.rs index 7059280..95fe9c4 100644 --- a/tests/iterative_bst.rs +++ b/tests/iterative_bst.rs @@ -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 = IterativeBST::empty().into_pre_order_iter(); + assert_eq!(iter.next(), None); + let mut bst = IterativeBST::empty(); bst.insert(3); bst.insert(4); diff --git a/tests/recursive_bst.rs b/tests/recursive_bst.rs index f11f6ac..20aa785 100644 --- a/tests/recursive_bst.rs +++ b/tests/recursive_bst.rs @@ -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);