dsa_rust/associative/
avl_tree_map.rs

1/*! A proper sorted map
2
3# About
4This sorted map uses the library's [AVL tree]() as its backing structure, providing _O(log(n))_ search, insert, and delete operations.
5
6# Example
7
8```rust
9    use dsa_rust::associative::avl_tree_map::TreeMap;
10
11    let text = "and the final paragraph clearly came from the heart,
12    or whatever cool yet sensitive organ Sadie kept in place of one.";
13
14    let mut map = TreeMap::<char, usize>::new();
15
16    // SAFETY: This is a thing
17    unsafe {}
18
19    for e in text.chars() {
20        if map.contains(e) {
21            let old = map.remove(e).unwrap();
22            map.put(e, old.value() + 1);
23        } else {
24            map.put(e, 1);
25        }
26    }
27    println!("TreeMap character occurrence");
28    for e in map.iter() {
29        println!("{e:?}");
30    }
31
32    println!("\nTreeMap vowel occurrence");
33    for vowel in ['a', 'e', 'i', 'o', 'u', 'y'] {
34        eprintln!("{vowel}: {}", map.get(vowel).unwrap_or(&0));
35    }
36
37```
38
39```text
40TreeMap character occurrence
41('\n', 1)
42(' ', 24)
43(',', 1)
44('.', 1)
45('S', 1)
46('a', 12)
47('c', 4)
48('d', 2)
49('e', 14)
50('f', 3)
51('g', 2)
52('h', 5)
53('i', 5)
54('k', 1)
55('l', 5)
56('m', 2)
57('n', 6)
58('o', 7)
59('p', 4)
60('r', 8)
61('s', 2)
62('t', 7)
63('v', 2)
64('w', 1)
65('y', 2)
66
67TreeMap vowel occurrence
68a: 12
69e: 14
70i: 5
71o: 7
72u: 0
73y: 2
74```
75
76*/
77
78use crate::hierarchies::avl_tree::AVLTree;
79
80use std::borrow::Borrow;
81use std::cmp::Ordering;
82use std::fmt::Debug;
83
84/// The wrapper struct that allows TreeMap<K, V> to use AVLTree<T>.
85/// Because `T` is [Ord], Entry<K, V> must implement [Eq] and [PartialOrd],
86/// which themselves must implement [PartialEq].
87/// All traits use `key` for ordering.
88///
89/// See the [module-level documentation]() for more details.
90#[derive(Debug)]
91//#[derive(Debug, Eq, PartialEq, PartialOrd)]
92pub struct Entry<K, V> {
93    key: K,
94    value: V,
95}
96impl<K, V> Entry<K, V> {
97    pub fn key(&self) -> &K {
98        &self.key
99    }
100
101    pub fn value(&self) -> &V {
102        &self.value
103    }
104}
105impl<K: PartialEq, V> PartialEq for Entry<K, V> {
106    fn eq(&self, other: &Self) -> bool {
107        self.key == other.key
108    }
109}
110// Eq requires PartialEq
111impl<K: Eq, V> Eq for Entry<K, V> {}
112// PartialOrd requires PartialEq
113impl<K: PartialOrd, V> PartialOrd for Entry<K, V> {
114    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
115        self.key.partial_cmp(&other.key)
116    }
117}
118// Ord requires Eq + PartialOrd
119impl<K: Ord, V> Ord for Entry<K, V> {
120    fn cmp(&self, other: &Self) -> Ordering {
121        self.key.cmp(&other.key)
122    }
123}
124impl<K, V> Borrow<K> for Entry<K, V> {
125    fn borrow(&self) -> &K {
126        &self.key
127    }
128}
129
130///
131///
132/// See the [module-level documentation]() for more details.
133#[derive(Debug)]
134pub struct TreeMap<K, V> {
135    tree: AVLTree<Entry<K, V>>,
136    size: usize,
137}
138impl<K, V> Default for TreeMap<K, V>
139where
140    K: Default + Eq + Ord + PartialEq,
141{
142    fn default() -> Self {
143        Self::new()
144    }
145}
146impl<K, V> TreeMap<K, V>
147where
148    K: Default + Eq + Ord + PartialEq,
149{
150    /// Constructor
151    pub fn new() -> Self {
152        Self {
153            tree: AVLTree::<Entry<K, V>>::new(),
154            size: 0,
155        }
156    }
157
158    /// Returns the number of elements in the map.
159    pub fn size(&self) -> usize {
160        self.size
161    }
162
163    /// Returns `true` if the map contains an entry associated with the given key.
164    pub fn contains(&self, key: K) -> bool {
165        self.tree.contains(&key)
166    }
167
168    /// Returns the value associated with the key, if `Some`.
169    pub fn get(&self, key: K) -> Option<&V> {
170        if let Some(val) = self.tree.get_node(&key) {
171            return Some(&val.value);
172        }
173        None
174    }
175
176    /// Inserts the entry into the map. If the key already exists, removes
177    /// and returns the old entry and inserts a new one. This allows for
178    /// situations where keys are `==` without being _identical_.
179    pub fn put(&mut self, key: K, value: V) -> Option<Entry<K, V>> {
180        let new_entry = Entry { key, value };
181        let old_entry = self.tree.remove(&new_entry.key);
182        self.tree.insert(new_entry);
183        if old_entry.is_none() {
184            self.size += 1;
185        }
186        old_entry
187    }
188
189    /// Mutates
190    pub fn mut_val_or() {}
191
192    /// Removes and returns the entry associated with the key:value pair,
193    /// if it exists in the map.
194    pub fn remove(&mut self, key: K) -> Option<Entry<K, V>> {
195        if self.tree.contains(&key) {
196            self.size -= 1;
197            return self.tree.remove(&key);
198        }
199        None
200    }
201
202    /// Returns an iterator over borrowed values. The resulting values
203    /// appear in sorted order.
204    ///
205    /// Example use:
206    /// ```rust
207    /// use dsa_rust::associative::probing_hash_table::HashMap;
208    /// let mut count: HashMap<char, u8> = HashMap::new();
209    /// let mut v = Vec::new();
210    /// for e in count.iter() {
211    ///     v.push(*e.0);
212    /// }
213    /// ```
214    pub fn iter(&self) -> Iter<'_, K, V> {
215        Iter {
216            iter: self.tree.iter(),
217        }
218    }
219}
220
221pub struct Iter<'a, K, V> {
222    //iter: std::slice::Iter<'a, Option<Entry<K, V>>>,
223    iter: crate::hierarchies::avl_tree::InOrderIter<
224        'a,
225        crate::associative::avl_tree_map::Entry<K, V>,
226    >,
227}
228impl<'a, K, V> Iterator for Iter<'a, K, V>
229where
230    K: Debug + PartialEq,
231    V: PartialEq,
232{
233    type Item = (&'a K, &'a V);
234
235    fn next(&mut self) -> Option<Self::Item> {
236        self.iter.next().map(|entry| (&entry.key, &entry.value))
237    }
238}
239
240#[test]
241// Generic type test
242fn avl_tree_map_test() {
243    //Creates a new hash map
244    let mut map = TreeMap::<&str, u8>::new();
245
246    assert_eq!(map.size(), 0);
247
248    // Illustrates that put() and get() work
249    map.put("Peter", 40);
250    assert_eq!(map.size(), 1);
251
252    // Illustrates that the map grows correctly
253    map.put("Brain", 39); // Grows the map
254    map.put("Remus", 22);
255    map.put("Bobson", 36); // Grows the map
256    map.put("Dingus", 18);
257    map.put("Dangus", 27); // Grows the map
258    assert_eq!(map.size(), 6);
259
260    // Underlying tree arena check
261    eprintln!("Initial state");
262    assert_eq!(map.tree.arena.len(), 6);
263    for e in map.tree.arena.iter() {
264        eprintln!("{e:?}")
265    }
266
267    // Illustrates that contains() works as intended
268    assert!(map.contains("Dingus"));
269
270    // Illustrates that put() returns old values and
271    // overwrites existing values upon collision...
272    let old = map.put("Peter", 41).unwrap();
273    assert_eq!(old.value, 40_u8);
274    let new_val = map.get("Peter").unwrap();
275    assert_eq!(*new_val, 41);
276    assert_eq!(map.size(), 6);
277
278    // Underlying tree arena check
279    eprintln!("After replacement");
280    assert_eq!(map.tree.arena.len(), 7);
281    for e in map.tree.arena.iter() {
282        eprintln!("{e:?}")
283    }
284
285    // Illustrates that removes entries by key and returns the value
286    assert!(map.contains("Dangus"));
287    let removed = map.remove("Dangus").unwrap();
288    assert_eq!(map.size(), 5);
289
290    // Underlying tree arena check
291    eprintln!("After removal");
292    assert_eq!(map.tree.arena.len(), 7);
293    for e in map.tree.arena.iter() {
294        eprintln!("{e:?}")
295    }
296
297    //assert_eq!(removed.key(), &"Dangus");
298    //assert_eq!(removed.value(), &27);
299    assert_eq!(removed.key, "Dangus");
300    assert_eq!(removed.value, 27);
301    assert!(!map.contains("Dangus"));
302
303    eprintln!("{map:#?}");
304
305    //panic!("MANUAL TEST FAILURE");
306}
307//
308//#[test]
309// //Tests the custom update value function
310//fn mut_val_test() {
311//    //Creates a new hash map
312//    let mut count = HashMap::<char, u8>::new();
313//    let phrase: &str = "Hello, sickos";
314//
315//    // Seeds the map with just the characters and a default value
316//    for char in phrase.chars() {
317//        count.put(char, 0);
318//    }
319//
320//    eprintln!("\nInitial state:");
321//    count.contents();
322//
323//    // Iterates through the map again, updating each value based on its occurence
324//    // NOTE: Can also be used as initial mapping operation with the same code,
325//    // but was split here for illustrative purposes
326//    for char in phrase.chars() {
327//        count.mut_val_or(char, |x| *x += 1, 1);
328//    }
329//
330//    // Pretty-prints the contents of the map
331//    eprintln!("\nModified:");
332//    count.contents();
333//
334//    // Uncomment to trigger debug print
335//    //assert!(count.is_empty());
336//}
337//
338#[test]
339// Tests that the structure is iterable
340fn iter_test() {
341    //Creates a new hash map of the frequence letters in the given phrase
342    let mut map = TreeMap::<usize, char>::new();
343    for (index, char) in "acbjfed".chars().enumerate() {
344        map.put(index, char); // index is key, char is value
345    }
346
347    // Indicates that the map is indeed sorted
348    eprintln!("\nSorted map:");
349    for e in map.tree.iter() {
350        eprintln!("{e:?}")
351    }
352
353    // Prints only the middle values based on key range
354    // which should be "b, j, f, e"
355    eprintln!("\nPrint values for indexes 2..=5:");
356    for e in 2..=5 {
357        let val = map.get(e).unwrap();
358        eprintln!("{val:?}");
359    }
360
361    //let text = "Not the most elegant text, but it sure
362    //    does the trick when you need it. I could go on and on and on,
363    //but instead Id rather just let the text explain itself in order to Illustrate
364    //    what this test is all about. Then again Im not sure I could do this without
365    //    just a little rambling, amirite? You're the kind of person that
366    //    gets it, I think.";
367
368    let text = "and the final paragraph clearly came from the heart, 
369    or whatever cool yet sensitive organ Sadie kept in place of one.";
370
371    // Establishes parity with the std BTreeMap
372    //let mut map = std::collections::BTreeMap::<char, usize>::new();
373    //for e in text.chars() {
374    //    if map.contains_key(&e) {
375    //        let old = map.remove(&e).unwrap();
376    //        map.insert(e, old + 1);
377    //    } else {
378    //        map.insert(e, 1);
379    //    }
380    //}
381    //eprintln!("\nBTreeMap character occurrence");
382    //for e in map.iter() {
383    //    eprintln!("{e:?}");
384    //}
385
386    // Second attempt with custom TreeMap
387    let mut map = TreeMap::<char, usize>::new();
388    for e in text.chars() {
389        if map.contains(e) {
390            let old = map.remove(e).unwrap();
391            map.put(e, old.value + 1);
392        } else {
393            map.put(e, 1);
394        }
395    }
396    eprintln!("\nTreeMap character occurrence");
397
398    //for e in map.tree.iter() {
399    //    eprintln!("({:?}, {})", e.key, e.value);
400    //}
401    for e in map.iter() {
402        eprintln!("{e:?}");
403    }
404
405    eprintln!("\nTreeMap vowel occurrence");
406    for vowel in ['a', 'e', 'i', 'o', 'u', 'y'] {
407        eprintln!("{vowel}: {}", map.get(vowel).unwrap_or(&0));
408    }
409    eprintln!("\nTreeMap occurrence of characters in my name");
410    for vowel in ['p', 'e', 't', 'r'] {
411        eprintln!("{vowel}: {}", map.get(vowel).unwrap_or(&0));
412    }
413
414    // Uncomment to trigger debug print
415    //panic!("MANUAL TEST FAILURE");
416}