dsa_rust/hierarchies/
arena_bst.rs

1/*! A safe, arena-based (indexed) binary search tree (BST)
2
3# About
4A binary search tree is a binary tree where the value of each node's child is less than or greater than its parent. Left children are less than their parents, and right children are greater than their parents.
5
6Due to common usage when implementing sorted map and set structures, this implementation does not accept duplicate entries.
7
8# Design
9The design uses a flat, [Vec]-backed structure with iterative navigation. This arena-allocated design provides robust, performant operations while keeping runtime checks to a minimum. The goal of this approach is to avoid unnecessary overhead with recursive operations and extra heap allocations, making it suitable for low-spec environments.
10
11# Example
12*/
13
14#![allow(dead_code)] // While we cook
15
16use std::cmp::Ordering;
17
18// Experiment in custom sum types
19enum Position {
20    // Key exists
21    Found(usize),
22    // Insertion information for new key
23    Parent(usize),
24}
25
26enum Side {
27    Left,
28    Right,
29}
30
31#[derive(Debug)]
32struct Node<T> {
33    index: usize,     // Strictly necessary?
34    value: Option<T>, // Wrapping the value allows us quick take() operations
35    parent: Option<usize>,
36    left: Option<usize>, // Explicit and simple
37    right: Option<usize>,
38    height: usize,
39}
40impl<T> Node<T> {
41    // Creates a new node with its current index, a value, and its parent (if Some).
42    // Guarantees that all nodes have a value.
43    fn new(index: usize, value: T, parent: Option<usize>) -> Self {
44        Node {
45            index,
46            value: Some(value),
47            parent,
48            left: None,
49            right: None,
50            height: 0,
51        }
52    }
53
54    // Gets the parent index of the node, if Some
55    fn get_parent(&self) -> Option<usize> {
56        self.parent
57    }
58
59    /// Returns a tuple of the node's children
60    /// 0 == left
61    /// 1 == right
62    fn get_children(&self) -> (Option<usize>, Option<usize>) {
63        (self.left, self.right)
64    }
65
66    // Returns a reference to the node's value, if Some
67    fn get_value(&self) -> Option<&T> {
68        self.value.as_ref()
69        //match &self.value {
70        //    Some(val) => Some(val),
71        //    None => None
72        //}
73    }
74}
75
76#[derive(Debug)]
77pub struct BinSearchTree<T> {
78    arena: Vec<Node<T>>,
79    root: Option<usize>, // Wont always be 0, and wont always be Some!
80}
81// Im just here to make Clippy happy
82impl<T> Default for BinSearchTree<T>
83where
84    T: Ord,
85{
86    fn default() -> Self {
87        Self::new()
88    }
89}
90impl<T> BinSearchTree<T>
91where
92    T: Ord,
93{
94    /// Creates a new, empty binary search tree.
95    pub fn new() -> Self {
96        BinSearchTree {
97            arena: Vec::new(),
98            root: None,
99        }
100    }
101
102    /// Creates a new, empty binary search tree with a given (growable) initial capacity.
103    pub fn new_with_capacity(size: usize) -> Self {
104        BinSearchTree {
105            arena: Vec::with_capacity(size),
106            root: Some(0),
107        }
108    }
109
110    /// The index of a found key or the root of
111    /// the sub-tree for its insertion point, if Some.
112    /// Returns None for an empty/corrupted tree.
113    /// Returns Option because the structure cannot guarantee initialized trees.
114    ///
115    /// This naive implementation can be used independently or within
116    /// a map that does _not_ support duplicates as it does not
117    /// discriminate between found and not found.
118    fn find_index(&self, key: &T) -> Option<usize>
119    where
120        T: Ord,
121    {
122        let mut current = self.root?; // Return None if empty
123        while let Some(node) = self.arena.get(current) {
124            let value = node.get_value()?; // Return None if corrupted
125            match value.cmp(key) {
126                Ordering::Less => {
127                    if let Some(right) = node.right {
128                        current = right;
129                    } else {
130                        break;
131                    } // return insert position
132                }
133                Ordering::Greater => {
134                    if let Some(left) = node.left {
135                        current = left;
136                    } else {
137                        break;
138                    } // return insert position
139                }
140                Ordering::Equal => break, // key found
141            }
142        }
143        Some(current)
144    }
145
146    /// Returns a `Position` that contains the index of the key if `Found`,
147    /// or the root of the sub-tree for its insertion point as `Parent`,
148    /// which could be 0 for an empty tree.
149    /// (All trees are guaranteed to be initialized)
150    fn find_index_enum(&self, _key: &T) -> Position {
151        if let Some(mut _index) = self.root {
152            return Position::Found(0);
153        }
154
155        // Search iteratively from the root to find a match or insertion parent
156        //while let Some(index) = self.arena.get(self.root.expect("Uh oh")) {
157        //    // SAFETY: Every node created with Node::new() is guaranteed to have a value
158        //    match index.value.as_ref().unwrap().cmp(key) {
159        //        Ordering::Less => {
160        //            if let Some(right) = index.right {
161        //                index = right;
162        //            } else {
163        //                break;
164        //            }
165        //        }
166        //        Ordering::Greater => {
167        //            if let Some(left) = index.left {
168        //                index = left;
169        //            } else {
170        //                break;
171        //            }
172        //        }
173        //        Ordering::Equal => break,
174        //    }
175        //}
176        //
177        //index
178        Position::Found(0)
179    }
180
181    /// Returns a tuple that contains information for whether the key exists
182    /// in the tree, and if so its index, if not, the insertion point (parent index)
183    /// Examples:
184    /// - The key is in the tree at index 23: (Some(23), None)
185    /// - The key is not in the index, but its parent should be index 7 (None, Some(7))
186    ///
187    /// Use the following pseudocode for contains():
188    /// ```text
189    /// match tree.find_index_exact(key).0 {
190    ///   Some(val) => true,
191    ///   None => false,
192    /// }
193    /// ```
194    ///
195    /// Use the following pseudocode to locate the insertion point:
196    /// ```text
197    /// if let Some(parent) = tree.find_index_exact(key).1 { ... }
198    /// ```
199    fn find_index_exact(&self, key: &T) -> (Option<usize>, Option<usize>) {
200        if let Some(mut index) = self.root {
201            //let mut index = self.root;
202            let mut tuple = (None, None);
203
204            while let Some(node) = self.arena.get(index) {
205                // SAFETY: Every node created with Node::new() is guaranteed to have a value
206                match node.value.as_ref().unwrap().cmp(key) {
207                    Ordering::Less => {
208                        // Go right, continue search
209                        if let Some(right) = node.right {
210                            index = right;
211                        } else {
212                            // The key should be the right child of index
213                            tuple = (None, Some(index));
214                            break;
215                        }
216                    }
217                    Ordering::Greater => {
218                        // Go left, continue search
219                        if let Some(left) = node.left {
220                            index = left;
221                        } else {
222                            // The key should be the left child of index
223                            tuple = (None, Some(index));
224                            break;
225                        }
226                    }
227                    // The key exists at index
228                    Ordering::Equal => {
229                        tuple = (Some(index), None);
230                        break;
231                    }
232                }
233            }
234
235            tuple
236        } else {
237            // The tree is empty
238            (None, None)
239        }
240    }
241
242    fn get_node(&self, index: usize) -> Option<&Node<T>> {
243        if index < self.arena.len() {
244            Some(&self.arena[index])
245        } else {
246            None
247        }
248    }
249
250    /// Inserts the given key into the tree. New insertions in a simple
251    /// BST are always leafs. This implementation does not guarantee uniqueness.
252    pub fn insert(&mut self, key: T) {
253        if !self.arena.is_empty() {
254            // Find the (presumptive) parent index
255            let parent = self.find_index(&key);
256
257            // If the parent == key, no op, otherwise its indeed the parent
258            //match &key.cmp(self.arena[parent_index].value.as_ref().unwrap()) {
259            match &key.cmp(
260                self.get_node(parent.expect(""))
261                    .unwrap()
262                    .get_value()
263                    .as_ref()
264                    .unwrap(),
265            ) {
266                // The key already exists, no op
267                Ordering::Equal => {}
268                // The key is less than the value at the index, go left
269                Ordering::Less => {
270                    // New node is a left child of parent
271                    self.arena[parent.expect("")].left = Some(self.arena.len())
272                    //self.get_node(parent).unwrap().get_children().0 = Some(self.arena.len())
273                }
274                // The key is greater than the value at the index, go right
275                Ordering::Greater => {
276                    // parent is true!
277                    // New node is a right child of parent
278                    self.arena[parent.expect("")].right = Some(self.arena.len())
279                }
280            }
281
282            // Create & insert the node
283            self.arena.push(Node::new(self.arena.len(), key, parent));
284        } else {
285            // The list is empty, insert a new root
286            self.arena.push(Node::new(0, key, None));
287        }
288    }
289
290    fn is_leaf(&self, index: usize) -> Result<bool, &str> {
291        match self.get_node(index) {
292            Some(val) => {
293                if val.get_children() == (None, None) {
294                    Ok(true)
295                } else {
296                    Ok(false)
297                }
298            }
299            None => Err("Invalid index"),
300        }
301    }
302
303    pub fn remove(&mut self, key: T) -> Option<T> {
304        // Exists with None if the key is not in the tree
305        if let Some(index) = self.find_index(&key) {
306            //let index = self.find_index(&key);
307
308            // Check if the key is actually in the tree by
309            // checking if the index represents the key or its parent
310            //
311            // The key is in the index
312            if self.arena[index].value.as_ref().unwrap() == &key {
313                // Case 1) The node to delete has two children
314                if self.arena[index].left.is_some() && self.arena[index].right.is_some() {
315                    // TODO: Implement
316
317                    // Get the node, take its value
318                    self.arena[index].value.take()
319
320                // Case 2) The node has only one child
321                } else if self.arena[index].left.is_some() || self.arena[index].right.is_some() {
322                    // Update the parent's child pointer to the removed node's child
323                    if self.arena[index].parent.is_some() {
324                        // Determine whether the removed is the right or left child of its parent
325                        let parent = self.arena[index].parent.unwrap();
326
327                        // The removed node is the right child of its parent
328                        if self.arena[parent].right.as_ref().unwrap() == &index {
329                            // The removed node only has a left child
330                            if self.arena[index].left.is_some() {
331                                // Update the parent's right child pointer to the removed node's left
332                                // child
333                                self.arena[parent].right = Some(self.arena[index].left?);
334                                // Update the removed node's left child to point to the removed node's
335                                // parent
336                                let child = self.arena[index].left.unwrap();
337                                self.arena[child].parent = Some(parent);
338                            // The removed node only has a right child
339                            } else {
340                                // Update the parent's right child pointer to the removed node's right
341                                // child
342                                self.arena[parent].right = Some(self.arena[index].right?);
343                                // Update the removed node's right child to point to the removed node's
344                                // parent
345                                let child = self.arena[index].right.unwrap();
346                                self.arena[child].parent = Some(parent);
347                            }
348                        }
349                        // The removed node is the left child
350                        else {
351                            // The removed node only has a left child
352                            if self.arena[index].left.is_some() {
353                                // Update the parent's left child pointer to the removed node's left
354                                // child
355                                self.arena[parent].left = Some(self.arena[index].left?);
356                            // The removed node only has a right child
357                            } else {
358                                // Update the parent's left child pointer to the removed node's right
359                                // child
360                                self.arena[parent].left = Some(self.arena[index].right?);
361                            }
362                        }
363                    }
364
365                    // Get the node, take/return its value
366                    self.arena[index].value.take()
367
368                // Case 3) The node has no children
369                } else {
370                    None
371                }
372
373                // update the parent's child pointer
374                // update the replacement node's parent pointer
375            }
376            // The key is not in the tree; no op
377            else {
378                None
379            }
380        } else {
381            None
382        }
383    }
384
385    /// Produces a "snapshot" iterator over immutable references to the
386    /// tree in its current state.
387    pub fn iter(&self) -> InOrderIter<'_, T> {
388        InOrderIter::new(&self.arena[self.root.expect("IDK man")])
389    }
390}
391
392pub struct InOrderIter<'a, T> {
393    stack: Vec<&'a Node<T>>,
394    current: Option<&'a Node<T>>,
395}
396impl<'a, T> InOrderIter<'a, T> {
397    fn new(root: &'a Node<T>) -> Self {
398        Self {
399            stack: Vec::new(),
400            current: Some(root),
401        }
402    }
403}
404//impl<'a, T> Iterator for InOrderIter<'a, T> {
405//    type Item = &'a T;
406//
407//    fn next(&mut self) -> Option<Self::Item> {
408//        while let Some(node) = self.current {
409//            self.stack.push(node);
410//            self.current = item.arena[node.left];
411//        }
412//
413//        self.stack.pop().map(|node| {
414//            self.current = node.right.as_deref();
415//            &node.value
416//        })
417//    }
418//}
419
420//#[test]
421//fn basic_bst() {
422//    let mut bst: BinSearchTree<u8> = BinSearchTree::new();
423//
424//    // Produces a BST
425//    let v = [31, 13, 23, 39, 41, 43, 8, 17, 19];
426//    for e in v.iter() {
427//        bst.insert(*e);
428//    }
429//
430//    eprintln!("{bst:#?}");
431//    assert_eq!(bst.arena[bst.root.expect("No root")].value, Some(31));
432//    let root_node = &bst.arena[bst.root.expect("nah, brah")];
433//    assert_eq!(bst.arena[root_node.left.unwrap()].value, Some(13));
434//    assert_eq!(bst.arena[root_node.right.unwrap()].value, Some(39));
435//}