dsa_rust/hierarchies/avl_tree.rs
1/*! A safe, arena-backed (indexed) AVL tree
2
3# About
4Adelson-Velsky and Landis (AVL) trees represent theoretically optimal balanced binary search trees. AVL trees guarantee _~1.44 * log(n)_ height, and provide _O(log(n))_ search, insert, and delete operations. Red-black trees tend to be more popular even though they only guarantee _<= 2 * log(n)_ height. The imperfect height is offset by the fact that red-black trees often require fewer rotations, and the average number of rebalance operations is fewer than with AVL trees.
5
6# Design
7The design uses a flat, [Vec]-backed structure with iterative (read non-recursive) navigation. This arena-allocated design provides robust, performant operations while keeping runtime checks to a minimum. The goal of this approach is to avoid unnecessary overhead with recursive operations and extra heap allocations, making it suitable for low-spec environments.
8
9The structure trades spatial efficiency for _O(1)_ insert operations. All "pointers" represent absolute positions (as indexes) and cannot be re-calculated in less than _O(n)_ time. Thus, `remove(key)` operations do not actually shrink the physical size of the structure, leaving a `None` "hole" in the removed node's place. The structure can only grow.
10
11Due to common usage when implementing sorted map and set structures, this implementation does not accept duplicate entries by default. The structure contains an internal `SearchResult` enum that allows for duplicates by way of `Ordering::Equal`, but it is yet implemented in this version.
12
13# Example
14```rust
15 use dsa_rust::hierarchies::avl_tree::AVLTree;
16
17 let mut tree: AVLTree<u8> = AVLTree::new();
18
19 // Create the following AVL tree
20 //
21 // 39
22 // / \
23 // 17 41
24 // / \ \
25 // 13 23 43
26 // / / \
27 // 8 19 31
28 //
29 let v = [31, 13, 23, 39, 41, 43, 8, 17, 19];
30 for e in v.iter() {
31 tree.insert(*e);
32 }
33 assert_eq!(tree.get_root(), Some(&39)); // Prove that its properly rooted
34
35
36 // Remove 41 which results in the following restructure
37 //
38 // 17
39 // / \
40 // 13 39
41 // / / \
42 // 8 23 43
43 // / \
44 // 19 31
45 //
46 assert!(tree.contains(&41)); // Prove that its here today
47 let removed = tree.remove(&41).unwrap();
48 assert_eq!(removed, 41);
49 assert!(!tree.contains(&41)); // ...and gone tomorrow
50
51 tree.insert(34);
52 tree.insert(67);
53 tree.insert(2);
54 tree.insert(4);
55 tree.insert(5);
56 tree.insert(1);
57
58 // The tree is still intact, and its root has shifted
59 assert_eq!(tree.get_root().unwrap(), &31);
60
61 // In-order "snapshot" iterator
62 let mut sorted = Vec::new();
63 for e in tree.iter() {
64 sorted.push(*e)
65 }
66 assert_eq!(sorted, [1, 2, 4, 5, 8, 13, 17, 19, 23, 31, 34, 39, 43, 67]);
67```
68*/
69
70use std::borrow::Borrow;
71use std::cmp::{max, Ordering};
72
73// Custom sum type for search algorithm
74enum SearchResult {
75 // The tree is empty (and uninitialized)
76 None,
77 // Index of a found key
78 Exists(usize),
79 // Index for insertion of a new key
80 Parent(usize),
81 //Parent { index: usize, side: Side },
82}
83
84//#[derive(PartialEq)]
85enum Side {
86 Left,
87 Right,
88}
89// NOTE: Implementing Not provides the ability to use the
90// logical negation operator !. Implementing a custom
91// opposite() does the same thing, but more explicitly.
92// The choice to implement Not for &Side instead of Side
93// allows the re-use of Side without making it Copy/Clone.
94// Example:
95// let subtree = self.arena[child_idx].child(!side);
96// let subtree = self.arena[child_idx].child(opposite(side));
97impl<'a> std::ops::Not for &'a Side {
98 type Output = &'a Side;
99 fn not(self) -> &'a Side {
100 match self {
101 Side::Left => &Side::Right,
102 Side::Right => &Side::Left,
103 }
104 }
105}
106fn opposite(side: &Side) -> &Side {
107 match side {
108 Side::Left => &Side::Right,
109 Side::Right => &Side::Left,
110 }
111}
112
113#[derive(Debug)]
114pub struct AVLNode<T> {
115 value: Option<T>, // Option allows take() operations for efficient node removals
116 parent: Option<usize>, // None indicates the root of the tree
117 left: Option<usize>,
118 right: Option<usize>,
119 height: usize,
120}
121impl<T> AVLNode<T> {
122 // Creates a new node with its current index, a value, and its parent (if Some).
123 // Guarantees that all nodes have a value.
124 // All initial inserts are leafs before restructuring, so left and right are set to None.
125 fn new(value: T, parent: Option<usize>, height: usize) -> Self {
126 AVLNode {
127 value: Some(value),
128 parent,
129 left: None,
130 right: None,
131 height,
132 }
133 }
134
135 // Returns a reference to the node's value, if Some
136 fn get_value(&self) -> Option<&T> {
137 self.value.as_ref()
138 }
139
140 /// Get child index for a given side
141 fn child(&self, side: &Side) -> Option<usize> {
142 match side {
143 Side::Left => self.left,
144 Side::Right => self.right,
145 }
146 }
147
148 /// Set child index for a given side
149 fn set_child(&mut self, side: &Side, idx: Option<usize>) {
150 match side {
151 Side::Left => self.left = idx,
152 Side::Right => self.right = idx,
153 }
154 }
155}
156
157/// # About
158///
159/// See the [module-level documentation](crate::hierarchies::avl_tree) for more information.
160#[derive(Debug)]
161pub struct AVLTree<T> {
162 // Option wrapper for efficient take() operations during removal
163 // without incurring the wrath of O(n) resize ops
164 pub arena: Vec<Option<AVLNode<T>>>,
165 // Wont always be 0, and wont always be Some!
166 root: Option<usize>,
167}
168// Im just here to make Clippy happy
169impl<T> Default for AVLTree<T>
170where
171 T: Ord,
172{
173 fn default() -> Self {
174 Self::new()
175 }
176}
177impl<T> AVLTree<T>
178where
179 T: Ord,
180{
181 /// Creates a new, empty binary search tree.
182 pub fn new() -> Self {
183 AVLTree {
184 arena: Vec::new(),
185 root: None,
186 }
187 }
188
189 /// Creates a new, empty binary search tree with a given (growable) initial capacity.
190 pub fn new_with_capacity(size: usize) -> Self {
191 AVLTree {
192 arena: Vec::with_capacity(size),
193 root: Some(0),
194 }
195 }
196
197 /// Gets a reference to the value of a key, if Some.
198 pub fn get_node<Q>(&self, key: &Q) -> Option<&T>
199 where
200 Q: Ord + ?Sized,
201 //T::Key: std::borrow::Borrow<Q>,
202 T: Borrow<Q>,
203 {
204 match self.search(key) {
205 SearchResult::Exists(index) => self.node(index).get_value(),
206 _ => None,
207 }
208 }
209
210 pub fn get_root(&self) -> Option<&T> {
211 if let Some(node) = self.root {
212 self.node(node).get_value()
213 } else {
214 None
215 }
216 }
217
218 /// Returns true if the key exists in the tree.
219 pub fn contains<Q>(&self, key: &Q) -> bool
220 where
221 Q: Ord + ?Sized,
222 T: Borrow<Q>,
223 {
224 matches!(self.search(key), SearchResult::Exists(_))
225 }
226
227 /// Inserts the given key into the tree maintaining an AVL structure.
228 ///
229 /// NOTE: Does not handle duplicate keys by convention, but may overwrite values for
230 /// arbitrarily complex T with custom Ordering.
231 pub fn insert(&mut self, key: T)
232 where
233 T: Ord,
234 {
235 // Pass &T::Key to search; search itself is generic over Q
236 match self.search(&key) {
237 SearchResult::Parent(parent) => {
238 // Determine child position
239 let new_idx = self.arena.len();
240 // SAFETY: Parent is guaranteed by search() enums
241 //if let Some(val) = &self.arena[parent].as_mut().unwrap().value {
242 if let Some(val) = &self.node_mut(parent).value {
243 match key.cmp(val) {
244 Ordering::Less => {
245 //self.arena[parent].as_mut().unwrap().left = Some(new_idx);
246 self.node_mut(parent).left = Some(new_idx);
247 }
248 Ordering::Greater => {
249 //self.arena[parent].as_mut().unwrap().right = Some(new_idx);
250 self.node_mut(parent).right = Some(new_idx);
251 }
252 Ordering::Equal => {}
253 }
254 };
255
256 // Insert new node
257 self.arena.push(Some(AVLNode::new(key, Some(parent), 1)));
258
259 // Walk up the tree to update heights and rebalance
260 let mut current = Some(parent);
261 while let Some(idx) = current {
262 self.update_node_height(idx);
263 self.restructure(idx);
264 //current = self.arena[idx].as_mut().unwrap().parent;
265 current = self.node_mut(idx).parent;
266 }
267 }
268 SearchResult::None => {
269 // Empty tree, insert root
270 let new_node = AVLNode::new(key, None, 1);
271 self.arena.push(Some(new_node));
272 self.root = Some(0);
273 }
274 SearchResult::Exists(_) => {}
275 }
276 }
277
278 /// Removes and returns an element from the AVL tree as an owned value.
279 pub fn remove<Q>(&mut self, key: &Q) -> Option<T>
280 where
281 Q: Ord + ?Sized,
282 T: Borrow<Q>,
283 {
284 //let target_index = match self.search(key.key()) {
285 let target_index = match self.search(key) {
286 SearchResult::Exists(idx) => idx,
287 _ => return None,
288 };
289
290 // Step 1: Find node to physically remove (node with ≤1 child)
291 let mut remove_index = target_index;
292 if self.node(remove_index).left.is_some() && self.node(remove_index).right.is_some() {
293 // Node has two children: find in-order successor
294 let mut succ_index = self.node(remove_index).right.unwrap();
295 while let Some(left) = self.node(succ_index).left {
296 succ_index = left;
297 }
298
299 // Move successor's value into target node
300 //let succ_value = self.arena[succ_index].take().unwrap().value;
301 //self.node_mut(remove_index).value = succ_value;
302
303 // 1. Take the value out of the successor node.
304 let succ_value = self.node_mut(succ_index).value.take();
305
306 // 2. Replace the target's value with the successor's,
307 // getting the original target value back.
308 let original_value = self
309 .node_mut(target_index)
310 .value
311 .replace(succ_value.unwrap());
312
313 // 3. Place the original target value into the successor node,
314 // which we are about to remove.
315 self.node_mut(succ_index).value = original_value;
316
317 // Now, the successor node can be safely removed, and it
318 // contains the correct value to return.
319
320 // Now remove the successor node (guaranteed ≤1 child)
321 remove_index = succ_index;
322 }
323
324 // Step 2: Identify the child of the node to remove (if any)
325 let child_index = self
326 .node(remove_index)
327 .left
328 .or(self.node(remove_index).right);
329
330 // Step 3: Update parent to point to the child
331 let parent_index = self.node(remove_index).parent;
332 if let Some(p_idx) = parent_index {
333 let parent = self.node_mut(p_idx);
334 if parent.left == Some(remove_index) {
335 parent.left = child_index;
336 } else {
337 parent.right = child_index;
338 }
339 } else {
340 // Removing root
341 self.root = child_index;
342 }
343
344 // Step 4: Update child's parent
345 if let Some(c_idx) = child_index {
346 self.node_mut(c_idx).parent = parent_index;
347 }
348
349 // Step 5: Take the node for return
350 let removed_value = self.arena[remove_index].take().map(|n| n.value);
351
352 // Step 6: Walk up ancestors to update heights and rebalance
353 let mut current = parent_index;
354 while let Some(idx) = current {
355 self.update_node_height(idx);
356 self.restructure(idx);
357 current = self.node(idx).parent;
358 }
359
360 removed_value?
361 }
362
363 /// Produces a "snapshot" iterator over immutable references to the
364 /// tree in its current state.
365 pub fn iter(&self) -> InOrderIter<'_, T> {
366 InOrderIter::new(&self.arena, self.root)
367 }
368
369 // Utility functions
370 ////////////////////
371
372 /// Immutable node accessor
373 fn node(&self, index: usize) -> &AVLNode<T> {
374 //self.arena[index]
375 // .as_ref()
376 // .expect("Error: Invalid immutable node access")
377 unsafe {
378 self.arena.get_unchecked(index)
379 .as_ref()
380 .expect("Error: Invalid immutable node access")
381 }
382 }
383
384 /// Mutable node accessor
385 fn node_mut(&mut self, index: usize) -> &mut AVLNode<T> {
386 //self.arena[index]
387 // .as_mut()
388 // .expect("Error: Invalid mutable node access")
389 unsafe {
390 self.arena.get_unchecked_mut(index)
391 .as_mut()
392 .expect("Error: Invalid mutable node access")
393 }
394 }
395
396 /// Returns a `SearchResult` enum with the following variants:
397 /// - None: Indicates an empty tree
398 /// - Parent: The key is not in the tree, but can be inserted at the parent index value
399 /// - Exists: The key was found in the tree; The caller can decide how to use this index
400 /// to deal with multi-maps and sets
401 ///
402 /// SAFETY: May panic if a node does not contain a value, but that
403 /// would violate the AVL tree invariant, so its highly unlikely, and only present to
404 /// handle the possibility of corrupted structures.
405 // Original impl: WORKS for T
406 fn search<Q>(&self, key: &Q) -> SearchResult
407 where
408 Q: Ord + ?Sized,
409 T: Borrow<Q>,
410 {
411 // Early return for empty structures
412 if self.arena.is_empty() {
413 return SearchResult::None;
414 };
415
416 // Sets the starting point for the search
417 // Safety: Valueless nodes violate the AVL tree invariant
418 let mut current = self
419 .root
420 .expect("Error: Root should always contain a value");
421
422 // Uses iterative loop instead of recursive search
423 // because fuck stack overflows (and recursion)
424 loop {
425 //if let Some(val) = &self.arena[current] {
426 if let Some(val) =
427 unsafe { &self.arena.get_unchecked(current) } {
428 // Converts &AVLNode<T> to &T
429 // Safety: Valueless nodes violate the AVL tree invariant
430 let value = val
431 .get_value()
432 .expect("Error: Node does not contain a value");
433
434 let value_key: &Q = value.borrow();
435
436 match value_key.cmp(key) {
437 // Go right or return parent
438 Ordering::Less => {
439 if let Some(right) = val.right {
440 current = right;
441 } else {
442 return SearchResult::Parent(current);
443 }
444 }
445 // Go left or return parent
446 Ordering::Greater => {
447 if let Some(left) = val.left {
448 current = left;
449 } else {
450 return SearchResult::Parent(current);
451 }
452 }
453 // The key already exists in the tree at the current index
454 Ordering::Equal => return SearchResult::Exists(current),
455 }
456 };
457 }
458 }
459
460 /// Updates the height of an arbitrary node in an AVL tree
461 /// where leaf nodes are defined as having height 1
462 fn update_node_height(&mut self, index: usize) {
463 let left = self
464 .node_mut(index)
465 .left
466 .map_or(0, |idx| self.node_mut(idx).height);
467 let right = self
468 .node_mut(index)
469 .right
470 .map_or(0, |idx| self.node_mut(idx).height);
471 // Works for internal and leaf nodes, because max(0, 0) + 1 = 1
472 self.node_mut(index).height = max(left, right) + 1
473 }
474
475 /// Rotate the subtree rooted at `root_idx` in the given direction.
476 /// `side` is the direction of the original heavy side (Side::Left or Side::Right).
477 fn rotate(&mut self, root_idx: usize, side: &Side) {
478 // Heavy child becomes the new root of the subtree
479 let child_idx = self
480 .node_mut(root_idx)
481 .child(side)
482 .expect("Rotation requires heavy child");
483
484 // Move child's opposite subtree into root's heavy side
485 //let subtree = self.arena[child_idx].child(opposite(side));
486 let subtree = self.node_mut(child_idx).child(!side);
487 self.node_mut(root_idx).set_child(side, subtree);
488 if let Some(sub_idx) = subtree {
489 self.node_mut(sub_idx).parent = Some(root_idx);
490 }
491
492 // Update parent pointers
493 let parent_idx = self.node_mut(root_idx).parent;
494 self.node_mut(child_idx).parent = parent_idx;
495
496 if let Some(p_idx) = parent_idx {
497 if self.node_mut(p_idx).left == Some(root_idx) {
498 self.node_mut(p_idx).left = Some(child_idx);
499 } else {
500 self.node_mut(p_idx).right = Some(child_idx);
501 }
502 } else {
503 self.root = Some(child_idx);
504 }
505
506 // Make old root the child of new root
507 self.node_mut(child_idx)
508 .set_child(opposite(side), Some(root_idx));
509 self.node_mut(root_idx).parent = Some(child_idx);
510
511 // Update heights
512 self.update_node_height(root_idx);
513 self.update_node_height(child_idx);
514 }
515
516 /// Determines left-heavy (>0) or right-heavy (<0) balance factors
517 /// for a given node index. The necessity for restructure
518 /// operations can be determined agnostically by
519 /// `abs(balance_factor(index)) >= 2`
520 fn balance_factor(&self, index: usize) -> isize {
521 let node = &self.node(index);
522 let left = node.left.map_or(0, |l| self.node(l).height as isize);
523 let right = node.right.map_or(0, |r| self.node(r).height as isize);
524 left - right
525 }
526
527 /// Rebalances the subtree rooted at `index`.
528 /// Performs single or double rotations as necessary.
529 fn restructure(&mut self, index: usize) {
530 // Not all inserts require restructuring
531 let balance = self.balance_factor(index);
532 if balance.abs() < 2 {
533 return;
534 }
535
536 // Determine heavy side
537 let heavy_side = if balance > 1 { Side::Left } else { Side::Right };
538
539 // Determine the child index for the heavy side
540 let child_idx = match self.node(index).child(&heavy_side) {
541 Some(idx) => idx,
542 // SAFETY: A None value on the child violates the AVL invariant
543 None => panic!("Error: Heavy child is None"),
544 };
545
546 // Double rotation check
547 //let child_balance = self.balance_factor(child_idx);
548 //if heavy_side == Side::Left && child_balance < 0 {
549 // self.rotate(child_idx, &Side::Right);
550 //} else if heavy_side == Side::Right && child_balance > 0 {
551 // self.rotate(child_idx, &Side::Left);
552 //}
553 match (&heavy_side, self.balance_factor(child_idx)) {
554 // LR
555 (Side::Left, b) if b < 0 => self.rotate(child_idx, &Side::Right),
556 // RL
557 (Side::Right, b) if b > 0 => self.rotate(child_idx, &Side::Left),
558 // Keep the compiler happy
559 _ => {}
560 }
561
562 // Single rotation on parent
563 self.rotate(index, &heavy_side);
564 }
565}
566
567pub struct InOrderIter<'a, T> {
568 arena: &'a [Option<AVLNode<T>>],
569 stack: Vec<usize>, // store indices, not references
570 current: Option<usize>,
571}
572impl<'a, T> InOrderIter<'a, T> {
573 fn new(arena: &'a [Option<AVLNode<T>>], root: Option<usize>) -> Self {
574 Self {
575 arena,
576 stack: Vec::new(),
577 current: root,
578 }
579 }
580}
581impl<'a, T> Iterator for InOrderIter<'a, T> {
582 type Item = &'a T;
583
584 fn next(&mut self) -> Option<Self::Item> {
585 while let Some(idx) = self.current {
586 if let Some(node) = self.arena[idx].as_ref() {
587 self.stack.push(idx);
588 self.current = node.left;
589 continue;
590 } else {
591 // Node was removed, skip
592 self.current = None;
593 }
594 }
595
596 if let Some(idx) = self.stack.pop() {
597 if let Some(node) = self.arena[idx].as_ref() {
598 self.current = node.right;
599 node.value.as_ref()
600 } else {
601 // Skip removed node
602 self.next()
603 }
604 } else {
605 None
606 }
607 }
608}
609
610#[test]
611fn avl_construction() {
612 let mut tree: AVLTree<u8> = AVLTree::new();
613
614 let v = [31, 13, 23, 39, 41, 43, 8, 17, 19];
615 // Produces the following AVL tree
616 //
617 // 39
618 // / \
619 // 17 41
620 // / \ \
621 // 13 23 43
622 // / / \
623 // 8 19 31
624 //
625 for e in v.iter() {
626 tree.insert(*e);
627 }
628
629 // Tests that the root is being updated properly
630 assert_eq!(tree.get_root().unwrap(), &39);
631 assert_eq!(tree.node(tree.root.expect("You fucked up")).value, Some(39));
632 let root_node = &tree.node(tree.root.expect("nah, brah"));
633 assert_eq!(tree.node(root_node.left.unwrap()).value, Some(17));
634 assert_eq!(tree.node(root_node.right.unwrap()).value, Some(41));
635 assert_eq!(tree.node(0).left, None);
636 assert_eq!(tree.node(0).right, None);
637
638 assert_eq!(tree.node(tree.node(7).left.unwrap()).value, Some(13));
639 assert_eq!(tree.node(tree.node(7).right.unwrap()).value, Some(23));
640
641 let mut sorted = Vec::new();
642 for e in tree.iter() {
643 sorted.push(*e)
644 }
645 assert_eq!(sorted, [8, 13, 17, 19, 23, 31, 39, 41, 43]);
646
647 let mut tree: AVLTree<u8> = AVLTree::new();
648 let v = [1, 2, 3, 4, 5, 6, 7];
649 // Produces the following AVL tree
650 //
651 // 4
652 // / \
653 // 2 6
654 // / \ / \
655 // 1 3 5 7
656 //
657 for e in v.iter() {
658 tree.insert(*e);
659 }
660
661 assert_eq!(tree.get_root().unwrap(), &4);
662 assert_eq!(tree.node(tree.root.expect("You fucked up")).value, Some(4));
663 let root_node = &tree.node(tree.root.expect("nah, brah"));
664 assert_eq!(tree.node(root_node.left.unwrap()).value, Some(2));
665 assert_eq!(tree.node(root_node.right.unwrap()).value, Some(6));
666 assert_eq!(tree.node(0).left, None);
667 assert_eq!(tree.node(0).right, None);
668
669 assert_eq!(tree.node(tree.node(5).left.unwrap()).value, Some(5));
670 assert_eq!(tree.node(tree.node(5).right.unwrap()).value, Some(7));
671
672 let mut sorted = Vec::new();
673 for e in tree.iter() {
674 sorted.push(*e)
675 }
676 assert_eq!(sorted, [1, 2, 3, 4, 5, 6, 7]);
677}
678
679#[test]
680fn avl_removals() {
681 let mut tree: AVLTree<u8> = AVLTree::new();
682
683 // Construct the following AVL tree
684 //
685 // 39
686 // / \
687 // 17 41
688 // / \ \
689 // 13 23 43
690 // / / \
691 // 8 19 31
692 //
693 let v = [31, 13, 23, 39, 41, 43, 8, 17, 19];
694 for e in v.iter() {
695 tree.insert(*e);
696 }
697
698 // Remove 31 which results in the following AVL tree
699 //
700 // 39
701 // / \
702 // 17 41
703 // / \ \
704 // 13 23 43
705 // / /
706 // 8 19
707 //
708 assert_eq!(tree.get_root().unwrap(), &39);
709 assert!(tree.contains(&31));
710 let removed = tree.remove(&31).unwrap();
711 assert_eq!(removed, 31);
712 assert!(!tree.contains(&31));
713
714 assert_eq!(tree.node(tree.node(2).left.expect("")).value, Some(19));
715 assert_eq!(tree.node(2).right, None);
716
717 // Remove 41 which results in the following AVL tree
718 //
719 // 17
720 // / \
721 // 13 39
722 // / / \
723 // 8 23 43
724 // /
725 // 19
726 //
727 assert!(tree.contains(&41));
728 let removed = tree.remove(&41).unwrap();
729 assert_eq!(removed, 41);
730 assert!(tree.remove(&41).is_none()); // Test that 41 was really removed
731 assert!(!tree.contains(&41));
732
733 // 39 now has L 23 and R 43
734 assert_eq!(tree.node(tree.node(3).left.expect("")).value, Some(23));
735 assert_eq!(tree.node(tree.node(3).right.expect("")).value, Some(43));
736
737 // 17 is now rooth with L 13 and R 39
738 assert_eq!(tree.get_root().unwrap(), &17);
739 assert_eq!(tree.node(tree.root.expect("You fucked up")).value, Some(17));
740 assert_eq!(tree.node(tree.node(7).left.expect("")).value, Some(13));
741 assert_eq!(tree.node(tree.node(7).right.expect("")).value, Some(39));
742 // The old root 39 now has L 23 and R 43
743 assert_eq!(tree.node(tree.node(3).left.expect("")).value, Some(23));
744 assert_eq!(tree.node(tree.node(3).right.expect("")).value, Some(43));
745
746 // Remove 8 which results in the following AVL tree
747 //
748 // 23
749 // / \
750 // 17 39
751 // / \ \
752 // 13 19 43
753 //
754 assert!(tree.contains(&8));
755 let removed = tree.remove(&8).unwrap();
756 assert_eq!(removed, 8);
757 assert!(tree.remove(&8).is_none()); // Test that 8 was really removed
758 assert!(!tree.contains(&8));
759
760 // 23 is now rooth with L 17 and R 39
761 assert_eq!(tree.get_root().unwrap(), &23);
762 assert_eq!(tree.node(tree.root.expect("You fucked up")).value, Some(23));
763 assert_eq!(tree.node(tree.node(2).left.expect("")).value, Some(17));
764 assert_eq!(tree.node(tree.node(2).right.expect("")).value, Some(39));
765 // The old root 17 now has L 13 and R 19
766 assert_eq!(tree.node(tree.node(7).left.expect("")).value, Some(13));
767 assert_eq!(tree.node(tree.node(7).right.expect("")).value, Some(19));
768}