From 3865ced818c0451f189e14b95930c93405792737 Mon Sep 17 00:00:00 2001 From: ScriptAndCompile Date: Thu, 13 Jun 2024 12:38:08 -0700 Subject: [PATCH 1/5] Added multiple docs to binary_search_tree.rs --- src/data_structures/binary_search_tree.rs | 239 +++++++++++++++++++++- 1 file changed, 228 insertions(+), 11 deletions(-) diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index 9470dd0..a590478 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -1,8 +1,35 @@ use std::cmp::Ordering; use std::ops::Deref; -/// This struct implements as Binary Search Tree (BST), which is a -/// simple data structure for storing sorted data +/// A binary search tree (BST) is a binary tree where each node has at most two children, and the +/// left child is less than the parent, and the right child is greater than the parent. This +/// implementation is a simple BST, and does not have any balancing mechanisms. +/// +/// # Examples +/// +/// ```rust +/// use rust_algorithms::data_structures::BinarySearchTree; +/// +/// let mut tree = BinarySearchTree::new(); +/// tree.insert(5); +/// tree.insert(3); +/// tree.insert(7); +/// tree.insert(1); +/// tree.insert(4); +/// tree.insert(6); +/// tree.insert(8); +/// +/// assert!(tree.search(&5)); +/// assert!(tree.search(&3)); +/// assert!(tree.search(&7)); +/// assert!(tree.search(&1)); +/// assert!(tree.search(&4)); +/// assert!(tree.search(&6)); +/// assert!(tree.search(&8)); +/// assert!(!tree.search(&0)); +/// assert!(!tree.search(&2)); +/// assert!(!tree.search(&9)); +/// ``` pub struct BinarySearchTree where T: Ord, @@ -12,10 +39,14 @@ where right: Option>>, } +/// Default implementation for BinarySearchTree +/// +/// Creates a new empty BinarySearchTree impl Default for BinarySearchTree where T: Ord, { + fn default() -> Self { Self::new() } @@ -25,7 +56,7 @@ impl BinarySearchTree where T: Ord, { - /// Create a new, empty BST + pub fn new() -> BinarySearchTree { BinarySearchTree { value: None, @@ -34,8 +65,31 @@ where } } - /// Find a value in this tree. Returns True iff value is in this - /// tree, and false otherwise + /// Find a value in this tree. + /// + /// # Returns + /// + /// `true`` if the value is in this tree, and `false` otherwise. + /// + /// # Arguments + /// + /// * `value` - The value to search for in this tree. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// tree.insert(5); + /// tree.insert(3); + /// + /// assert!(tree.search(&5)); + /// assert!(tree.search(&3)); + /// assert!(!tree.search(&0)); + /// assert!(!tree.search(&4)); + /// ``` pub fn search(&self, value: &T) -> bool { match &self.value { Some(key) => { @@ -64,12 +118,52 @@ where } } - /// Returns a new iterator which iterates over this tree in order + /// Creates an iterator which iterates over this tree in ascending order + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// let mut iter = tree.iter(); + /// + /// assert_eq!(iter.next().unwrap(), &3); + /// assert_eq!(iter.next().unwrap(), &5); + /// assert_eq!(iter.next().unwrap(), &7); + /// assert_eq!(iter.next(), None); + /// ``` pub fn iter(&self) -> impl Iterator { BinarySearchTreeIter::new(self) } - /// Insert a value into the appropriate location in this tree. + /// Inserts a value into the appropriate location in this tree. + /// + /// # Arguments + /// + /// * `value` - The value to insert into this tree. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// assert!(tree.search(&5)); + /// assert!(tree.search(&3)); + /// assert!(tree.search(&7)); + /// assert!(!tree.search(&0)); + /// assert!(!tree.search(&4)); + /// ``` pub fn insert(&mut self, value: T) { if self.value.is_none() { self.value = Some(value); @@ -97,7 +191,27 @@ where } } - /// Returns the smallest value in this tree + /// Gets the smallest value in this tree. + /// + /// # Returns + /// + /// The smallest value in this tree, or `None` if this tree is empty. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// assert!(tree.minimum().is_none()); + /// + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// assert_eq!(*tree.minimum().unwrap(), 3); + /// ``` pub fn minimum(&self) -> Option<&T> { match &self.left { Some(node) => node.minimum(), @@ -105,7 +219,27 @@ where } } - /// Returns the largest value in this tree + /// Gets the largest value in this tree. + /// + /// # Returns + /// + /// The largest value in this tree, or `None` if this tree is empty. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// assert!(tree.maximum().is_none()); + /// + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// assert_eq!(*tree.maximum().unwrap(), 7); + /// ``` pub fn maximum(&self) -> Option<&T> { match &self.right { Some(node) => node.maximum(), @@ -113,7 +247,34 @@ where } } - /// Returns the largest value in this tree smaller than value + /// Gets the largest value in this tree smaller than value + /// + /// # Arguments + /// + /// * `value` - The floor that limits the maximum value returned. + /// + /// # Returns + /// + /// The largest value in this tree smaller than value, or `None` if this tree is empty + /// or `value` is smaller than any contained value. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// assert_eq!(*tree.floor(&5).unwrap(), 5); + /// assert_eq!(*tree.floor(&4).unwrap(), 3); + /// assert_eq!(*tree.floor(&8).unwrap(), 7); + /// + /// assert_eq!(tree.floor(&0), None); + /// ``` pub fn floor(&self, value: &T) -> Option<&T> { match &self.value { Some(key) => { @@ -145,7 +306,34 @@ where } } - /// Returns the smallest value in this tree larger than value + /// Gets the smallest value in this tree larger than value. + /// + /// # Arguments + /// + /// * `value` - The ceil that limits the minimum value returned. + /// + /// # Returns + /// + /// The smallest value in this tree larger than value, or `None` if this tree is empty + /// or `value` is larger than any contained value. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// assert_eq!(*tree.ceil(&5).unwrap(), 5); + /// assert_eq!(*tree.ceil(&4).unwrap(), 5); + /// assert_eq!(*tree.ceil(&0).unwrap(), 3); + /// + /// assert_eq!(tree.ceil(&8), None); + /// ``` pub fn ceil(&self, value: &T) -> Option<&T> { match &self.value { Some(key) => { @@ -181,6 +369,9 @@ where } } +/// Iterator for BinarySearchTree +/// +/// Iterates over the tree in ascending order struct BinarySearchTreeIter<'a, T> where T: Ord, @@ -205,12 +396,38 @@ where } } +/// Iterator implementation for BinarySearchTree +/// +/// Iterates over the tree in ascending order impl<'a, T> Iterator for BinarySearchTreeIter<'a, T> where T: Ord, { type Item = &'a T; + /// Get the next value in the tree + /// + /// # Returns + /// + /// The next value in the tree, or `None` if the iterator is exhausted. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// tree.insert(5); + /// tree.insert(3); + /// tree.insert(7); + /// + /// let mut iter = tree.iter(); + /// + /// assert_eq!(iter.next().unwrap(), &3); + /// assert_eq!(iter.next().unwrap(), &5); + /// assert_eq!(iter.next().unwrap(), &7); + /// assert_eq!(iter.next(), None); + /// ``` fn next(&mut self) -> Option<&'a T> { if self.stack.is_empty() { None From d7191ef49a77783411255edad3af0552e0c11c2d Mon Sep 17 00:00:00 2001 From: ScriptAndCompile Date: Thu, 13 Jun 2024 12:38:58 -0700 Subject: [PATCH 2/5] Added to binary_search_tree.rs --- src/data_structures/binary_search_tree.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index a590478..de0df34 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -65,6 +65,27 @@ where } } + /// Determines if this tree is empty. + /// + /// # Returns + /// + /// `true`` if this tree is empty, and `false`` otherwise. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let mut tree = BinarySearchTree::new(); + /// + /// assert!(tree.is_empty()); + /// tree.insert(5); + /// assert!(!tree.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.value.is_none() + } + /// Find a value in this tree. /// /// # Returns From 3ea6cb5245295e8c977066d645b6602f34471d81 Mon Sep 17 00:00:00 2001 From: ScriptAndCompile Date: Thu, 13 Jun 2024 12:40:44 -0700 Subject: [PATCH 3/5] Added docs for new and default. --- src/data_structures/binary_search_tree.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index de0df34..3a9b898 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -47,6 +47,17 @@ where T: Ord, { + /// Create a new, empty `BinarySearchTree`. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let tree: BinarySearchTree = BinarySearchTree::default(); + /// + /// assert!(tree.is_empty()); + /// ``` fn default() -> Self { Self::new() } @@ -57,6 +68,17 @@ where T: Ord, { + /// Create a new, empty `BinarySearchTree`. + /// + /// # Examples + /// + /// ```rust + /// use rust_algorithms::data_structures::BinarySearchTree; + /// + /// let tree: BinarySearchTree = BinarySearchTree::new(); + /// + /// assert!(tree.is_empty()); + /// ``` pub fn new() -> BinarySearchTree { BinarySearchTree { value: None, From 8aaada4c7730623ab8e67e4fbf262cfdf803ac57 Mon Sep 17 00:00:00 2001 From: ScriptAndCompile Date: Thu, 13 Jun 2024 12:41:28 -0700 Subject: [PATCH 4/5] Removed pub from BinarySearchTreeIter since the struct is not public and it should only be created from inside the module itself. --- src/data_structures/binary_search_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index 3a9b898..8f3e602 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -426,7 +426,7 @@ impl<'a, T> BinarySearchTreeIter<'a, T> where T: Ord, { - pub fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter { + fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter { let mut iter = BinarySearchTreeIter { stack: vec![tree] }; iter.stack_push_left(); iter From 7076620d1e554114887cf8b7fab7fc65a10c29d1 Mon Sep 17 00:00:00 2001 From: ScriptAndCompile Date: Thu, 13 Jun 2024 13:28:26 -0700 Subject: [PATCH 5/5] Cargo fmt fix. again. Argh! --- src/data_structures/binary_search_tree.rs | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index 8f3e602..45c7d49 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -46,7 +46,6 @@ impl Default for BinarySearchTree where T: Ord, { - /// Create a new, empty `BinarySearchTree`. /// /// # Examples @@ -67,8 +66,7 @@ impl BinarySearchTree where T: Ord, { - - /// Create a new, empty `BinarySearchTree`. + /// Create a new, empty `BinarySearchTree`. /// /// # Examples /// @@ -374,7 +372,7 @@ where /// assert_eq!(*tree.ceil(&5).unwrap(), 5); /// assert_eq!(*tree.ceil(&4).unwrap(), 5); /// assert_eq!(*tree.ceil(&0).unwrap(), 3); - /// + /// /// assert_eq!(tree.ceil(&8), None); /// ``` pub fn ceil(&self, value: &T) -> Option<&T> { @@ -413,7 +411,7 @@ where } /// Iterator for BinarySearchTree -/// +/// /// Iterates over the tree in ascending order struct BinarySearchTreeIter<'a, T> where @@ -440,7 +438,7 @@ where } /// Iterator implementation for BinarySearchTree -/// +/// /// Iterates over the tree in ascending order impl<'a, T> Iterator for BinarySearchTreeIter<'a, T> where @@ -449,23 +447,23 @@ where type Item = &'a T; /// Get the next value in the tree - /// + /// /// # Returns - /// + /// /// The next value in the tree, or `None` if the iterator is exhausted. - /// + /// /// # Examples - /// + /// /// ```rust /// use rust_algorithms::data_structures::BinarySearchTree; - /// + /// /// let mut tree = BinarySearchTree::new(); /// tree.insert(5); /// tree.insert(3); /// tree.insert(7); - /// + /// /// let mut iter = tree.iter(); - /// + /// /// assert_eq!(iter.next().unwrap(), &3); /// assert_eq!(iter.next().unwrap(), &5); /// assert_eq!(iter.next().unwrap(), &7);