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