ds_bst/
bst.rs

1/// Implements a [Binary Search Tree](https://en.wikipedia.org/wiki/Binary_search_tree).
2/// This is a recursive data structure and left
3/// and right refers to sub trees.
4///
5/// Tree is an entry point for the root node. It's much simpler
6/// to create a tree form a vector.
7///
8/// # Example
9/// Implements binary search tree with traversal (inorder)
10///
11/// ```rust
12/// use ds_bst::BinarySearchTree;
13///
14/// let mut root = BinarySearchTree::from(vec![1,2,3,4,5,6,7,8,9]);
15/// root.insert(10);
16/// let ordered: Vec<_> = root.inorder();
17///
18/// let mut root2 = BinarySearchTree::new(5);
19/// root2.insert(1);
20/// root2.insert(6);
21/// ```
22///
23/// It also supports both consumable and non-cosumable iterator
24/// which returns values inorder.
25///
26/// ```rust
27/// use ds_bst::BinarySearchTree;
28/// let root = BinarySearchTree::from(vec![1,2,3,4,5,6,7,8,9]);
29/// for value in &root {
30///     // It will print values in-order traversal
31///     println!("{}", *value);
32/// }
33/// ```
34use std::cmp::{max};
35
36pub struct BinarySearchTree<T> {
37    val: T,
38    left: Option<Box<BinarySearchTree<T>>>,
39    right: Option<Box<BinarySearchTree<T>>>
40}
41
42impl<T: PartialOrd + Copy> BinarySearchTree<T> {
43    /// Contructor creates BinarySearchTree root node
44    pub fn new(v: T) -> BinarySearchTree<T> {
45        BinarySearchTree {
46            val: v,
47            left: None,
48            right: None
49        }
50    }
51    /// Delegates tree building to `BinarySearchTree::build_recursive()`
52    /// This sorts vector input and pass splice to tree builder.
53    pub fn from(mut data: Vec<T>) -> BinarySearchTree<T> {
54        data.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
55        let n = data.len() as isize;
56        let root = BinarySearchTree::build_recursive(&data[0..], 0, n-1);
57
58        match root {
59            None => { panic!("Empty node"); },
60            Some(r) => { *r }
61        }
62    }
63
64    /// Recursively builds tree maintaining BST properties.
65    /// Uses `O(n)` time.
66    pub fn build_recursive(data: &[T], start: isize, end: isize) -> Option<Box<BinarySearchTree<T>>> {
67
68        if start > end {
69            return None;
70        };
71
72        let mid = (start + end) / 2;
73
74        let root = BinarySearchTree {
75            val: data[mid as usize],
76            left: BinarySearchTree::build_recursive(&data, start, mid-1),
77            right: BinarySearchTree::build_recursive(&data, mid + 1, end)
78        };
79        Some(Box::new(root))
80    }
81
82    /// Inorder traverse tree which yields elements in sorted order.
83    /// Uses `O(n)` time.
84    pub fn inorder(&self) -> Vec<T> {
85        let mut ret: Vec<T> = Vec::new();
86
87        match self.left {
88            None => {},
89            Some(ref node) => {
90                let v = node.inorder();
91                ret.extend(v);
92            }
93        };
94        ret.push(self.val);
95        match self.right {
96            None => {},
97            Some(ref node) => {
98                let v = node.inorder();
99                ret.extend(v);
100            }
101        }
102        ret
103    }
104
105    /// Traverse tree in preorder.
106    /// Uses `O(n)` time.
107    pub fn preorder(&self) -> Vec<T> {
108        let mut ret: Vec<T> = Vec::new();
109
110        ret.push(self.val);
111        match self.left {
112            None => {},
113            Some(ref node) => {
114                let v = node.preorder();
115                ret.extend(v);
116            }
117        }
118        match self.right{
119            None => {},
120            Some(ref node) => {
121                let v = node.preorder();
122                ret.extend(v);
123            }
124        }
125        ret
126    }
127
128    /// Calculates tree maximum height
129    /// Worst case O(n)
130    pub fn height(&self) -> usize {
131        let hl: usize = match self.left {
132            None => { 0 },
133            Some(ref node) => {
134                node.height()
135            }
136        };
137
138        let hr: usize = match self.right{
139            None => { 0 },
140            Some(ref node) => {
141                node.height()
142            }
143        };
144
145        max(hl, hr) + 1
146    }
147
148    /// Inserts an element in a tree.
149    /// Uses `O(n)` time.
150    pub fn insert(&mut self, val: T) {
151        if self.val > val {
152            match self.left {
153                None => self.left = Some(Box::new(BinarySearchTree::new(val))),
154                Some(ref mut n) => n.insert(val)
155            }
156        } else {
157            match self.right {
158                None => self.right = Some(Box::new(BinarySearchTree::new(val))),
159                Some(ref mut n) => n.insert(val)
160            }
161        }
162    }
163
164
165    /// Checks if element exists in a tree.
166    /// Uses `O(n)` time.
167    pub fn exists(&self, val: T) -> bool {
168        if self.val == val {
169            return true;
170        }
171        if self.val > val {
172            return match self.left {
173                None => false,
174                Some(ref n) => n.exists(val)
175            };
176        }
177        if self.val < val {
178            return match self.right {
179                None => false,
180                Some(ref n) => n.exists(val)
181            };
182        }
183        false
184    }
185
186    /// Finds minimum element in a tree.
187    /// Uses `O(n)` time.
188    pub fn find_min(&self) -> T {
189        match self.left {
190            None => self.val,
191            Some(ref n) => n.find_min()
192        }
193    }
194
195    /// Finds maximum element in a tree.
196    /// Uses `O(n)` time.
197    pub fn find_max(&self) -> T {
198        match self.right {
199            None => self.val,
200            Some(ref n) => n.find_max()
201        }
202    }
203}
204
205/// BinarySearchTreeIterator
206pub struct BinarySearchTreeIter<'a, T> {
207    nodes: Vec<&'a T>
208}
209
210impl<'a, T> BinarySearchTreeIter<'a, T>
211    where
212        T: PartialOrd + Copy
213{
214    /// Construct nodes based on input tree. By default
215    /// it uses in-order traversal for iterator.
216    fn new(root: &'a BinarySearchTree<T>) -> Self {
217        let mut iter = BinarySearchTreeIter {
218            nodes: Vec::new()
219        };
220
221        iter.inorder(root);
222
223        iter
224    }
225
226    /// In-order tree traversal
227    fn inorder(&mut self, tree: &'a BinarySearchTree<T>) {
228        match tree.right {
229            None => {},
230            Some(ref node) => {
231                self.inorder(node);
232            }
233        };
234        self.nodes.push(&tree.val);
235        match tree.left {
236            None => {},
237            Some(ref node) => {
238                self.inorder(node);
239            }
240        }
241    }
242}
243
244/// Implement iterator for BinarySearchTreeIter
245/// nodes are stored in flat array. It just pop outs node
246impl<'a, T> Iterator for BinarySearchTreeIter<'a, T>
247    where
248        T: PartialOrd + Copy,
249{
250    type Item = &'a T;
251
252    fn next(&mut self) -> Option<Self::Item> {
253        self.nodes.pop()
254    }
255}
256
257/// implement consumable IntoIterator for BinarySearchTree
258impl<T> IntoIterator for BinarySearchTree<T>
259    where
260        T: PartialOrd + Copy,
261{
262    type Item = T;
263    type IntoIter = std::vec::IntoIter<Self::Item>;
264
265    fn into_iter(self) -> Self::IntoIter {
266        self.inorder().into_iter()
267    }
268}
269
270/// Implement non-consumable IntoIterator for BinarySearchTree
271impl<'a, T> IntoIterator for &'a BinarySearchTree<T>
272    where
273        T: PartialOrd + Copy {
274    type Item = &'a T;
275    type IntoIter = BinarySearchTreeIter<'a, T>;
276
277    fn into_iter(self) -> Self::IntoIter {
278        BinarySearchTreeIter::new(self)
279    }
280}
281
282
283#[cfg(test)]
284mod tests {
285    use super::BinarySearchTree;
286    #[test]
287    fn build() {
288        let mut root = BinarySearchTree::from(vec![10, 11, 5, 4, 1, 2, 3, 9 ,8, 7, 6]);
289        assert_eq!(root.val, 6);
290        root.insert(12);
291        assert_eq!(root.exists(12), true);
292        assert_eq!(root.exists(13), false);
293        assert_eq!(root.exists(1), true);
294        assert_eq!(root.find_min(), 1);
295        assert_eq!(root.find_max(), 12);
296
297        let sorted: Vec<_> = root.inorder();
298        assert_eq!(sorted, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
299
300        let preorder: Vec<_> = root.preorder();
301        assert_eq!(preorder, vec![6, 3, 1, 2, 4, 5, 9, 7, 8, 10, 11, 12]);
302    }
303    #[test]
304    fn build_from_node() {
305        let mut root = BinarySearchTree::new(5);
306        root.insert(4);
307        root.insert(6);
308        root.insert(3);
309        root.insert(2);
310        root.insert(8);
311
312        assert_eq!(root.find_max(), 8);
313        assert_eq!(root.find_min(), 2);
314    }
315    #[test]
316    fn even() {
317        let root = BinarySearchTree::from(vec![3,4,2,1]);
318        assert_eq!(root.val, 2);
319    }
320    #[test]
321    fn float() {
322        let mut root = BinarySearchTree::from(vec![1.1, 1.0, 1.5, 1.9, 1.7]);
323        assert_eq!(root.val, 1.5);
324        root.insert(1.8);
325        assert_eq!(root.exists(1.8), true);
326        assert_eq!(root.find_max(), 1.9);
327    }
328    #[test]
329    fn iterator_consumable() {
330        let root = BinarySearchTree::from(vec![1,2,3]);
331        let mut i = 1;
332
333        for v in root {
334            assert_eq!(v, i);
335            i = i + 1;
336        }
337        // root is now consumed and cannot be used here
338    }
339    #[test]
340    fn iterator_non_consumable() {
341        let root = BinarySearchTree::from(vec![1,2,3]);
342        let mut i = 1;
343        for v in &root {
344            assert_eq!(*v, i);
345            i = i + 1;
346        };
347
348        assert_eq!(root.find_max(), 3);
349        assert_eq!(root.height(), 2);
350    }
351    #[test]
352    fn height() {
353        let root = BinarySearchTree::from(vec![1]);
354        assert_eq!(root.height(), 1);
355
356        let root2 = BinarySearchTree::from(vec![11,20,29,32,41,65,50,91,72,99]);
357        assert_eq!(root2.height(), 4)
358    }
359}