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