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
284                .push(Node::new(self.arena.len(), key, parent));
285        } else {
286            // The list is empty, insert a new root
287            self.arena.push(Node::new(0, key, None));
288        }
289    }
290
291    fn is_leaf(&self, index: usize) -> Result<bool, &str> {
292        match self.get_node(index) {
293            Some(val) => {
294                if val.get_children() == (None, None) {
295                    Ok(true)
296                } else {
297                    Ok(false)
298                }
299            }
300            None => Err("Invalid index"),
301        }
302    }
303
304    pub fn remove(&mut self, key: T) -> Option<T> {
305        // Exists with None if the key is not in the tree
306        if let Some(index) = self.find_index(&key) {
307            //let index = self.find_index(&key);
308
309            // Check if the key is actually in the tree by
310            // checking if the index represents the key or its parent
311            //
312            // The key is in the index
313            if self.arena[index].value.as_ref().unwrap() == &key {
314                // Case 1) The node to delete has two children
315                if self.arena[index].left.is_some() && self.arena[index].right.is_some() {
316                    // TODO: Implement
317
318                    // Get the node, take its value
319                    self.arena[index].value.take()
320
321                // Case 2) The node has only one child
322                } else if self.arena[index].left.is_some() || self.arena[index].right.is_some() {
323                    // Update the parent's child pointer to the removed node's child
324                    if self.arena[index].parent.is_some() {
325                        // Determine whether the removed is the right or left child of its parent
326                        let parent = self.arena[index].parent.unwrap();
327
328                        // The removed node is the right child of its parent
329                        if self.arena[parent].right.as_ref().unwrap() == &index {
330                            // The removed node only has a left child
331                            if self.arena[index].left.is_some() {
332                                // Update the parent's right child pointer to the removed node's left
333                                // child
334                                self.arena[parent].right = Some(self.arena[index].left?);
335                                // Update the removed node's left child to point to the removed node's
336                                // parent
337                                let child = self.arena[index].left.unwrap();
338                                self.arena[child].parent = Some(parent);
339                            // The removed node only has a right child
340                            } else {
341                                // Update the parent's right child pointer to the removed node's right
342                                // child
343                                self.arena[parent].right = Some(self.arena[index].right?);
344                                // Update the removed node's right child to point to the removed node's
345                                // parent
346                                let child = self.arena[index].right.unwrap();
347                                self.arena[child].parent = Some(parent);
348                            }
349                        }
350                        // The removed node is the left child
351                        else {
352                            // The removed node only has a left child
353                            if self.arena[index].left.is_some() {
354                                // Update the parent's left child pointer to the removed node's left
355                                // child
356                                self.arena[parent].left = Some(self.arena[index].left?);
357                            // The removed node only has a right child
358                            } else {
359                                // Update the parent's left child pointer to the removed node's right
360                                // child
361                                self.arena[parent].left = Some(self.arena[index].right?);
362                            }
363                        }
364                    }
365
366                    // Get the node, take/return its value
367                    self.arena[index].value.take()
368
369                // Case 3) The node has no children
370                } else {
371                    None
372                }
373
374                // update the parent's child pointer
375                // update the replacement node's parent pointer
376            }
377            // The key is not in the tree; no op
378            else {
379                None
380            }
381        } else {
382            None
383        }
384    }
385
386    /// Produces a "snapshot" iterator over immutable references to the
387    /// tree in its current state.
388    pub fn iter(&self) -> InOrderIter<'_, T> {
389        InOrderIter::new(&self.arena[self.root.expect("IDK man")])
390    }
391}
392
393pub struct InOrderIter<'a, T> {
394    stack: Vec<&'a Node<T>>,
395    current: Option<&'a Node<T>>,
396}
397impl<'a, T> InOrderIter<'a, T> {
398    fn new(root: &'a Node<T>) -> Self {
399        Self {
400            stack: Vec::new(),
401            current: Some(root),
402        }
403    }
404}
405//impl<'a, T> Iterator for InOrderIter<'a, T> {
406//    type Item = &'a T;
407//
408//    fn next(&mut self) -> Option<Self::Item> {
409//        while let Some(node) = self.current {
410//            self.stack.push(node);
411//            self.current = item.arena[node.left];
412//        }
413//
414//        self.stack.pop().map(|node| {
415//            self.current = node.right.as_deref();
416//            &node.value
417//        })
418//    }
419//}
420
421//#[test]
422//fn basic_bst() {
423//    let mut bst: BinSearchTree<u8> = BinSearchTree::new();
424//
425//    // Produces a BST
426//    let v = [31, 13, 23, 39, 41, 43, 8, 17, 19];
427//    for e in v.iter() {
428//        bst.insert(*e);
429//    }
430//
431//    eprintln!("{bst:#?}");
432//    assert_eq!(bst.arena[bst.root.expect("No root")].value, Some(31));
433//    let root_node = &bst.arena[bst.root.expect("nah, brah")];
434//    assert_eq!(bst.arena[root_node.left.unwrap()].value, Some(13));
435//    assert_eq!(bst.arena[root_node.right.unwrap()].value, Some(39));
436//}