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