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}