diff --git a/src/lib.rs b/src/lib.rs index fe8319e..44876c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,10 +83,11 @@ //! assert_ne!(recursive_bst, RecursiveBST::new()); //! ``` -use std::cmp::{max, Ordering}; -use std::collections::VecDeque; use std::fmt::{Debug, Display, Formatter}; use std::vec::IntoIter; +use crate::node::{HeapNode, Node}; + +mod node; /// A trait containing all the common operations of Binary Search Trees. /// @@ -355,8 +356,6 @@ pub trait BinarySearchTree { fn into_level_order_iter(self) -> IntoIter; } -type HeapNode = Option>>; - /// A Recursive Binary Search Tree implementation, defined as `RecursiveBST` where T _must_ /// implement trait [Ord]. /// @@ -385,13 +384,6 @@ pub struct IterativeBST { size: usize, } -#[derive(Debug)] -struct Node { - value: T, - left: HeapNode, - right: HeapNode, -} - impl IterativeBST { /// Creates an empty `IterativeBST` /// @@ -2111,562 +2103,4 @@ impl BinarySearchTree for RecursiveBST { Node::recursive_consume_level_order_vec(self.root, &mut elements); elements.into_iter() } -} - -impl Node { - fn new(value: T) -> Node { - Node { - value, - left: None, - right: None, - } - } - - fn iterative_insert(mut root: &mut HeapNode, value: T) -> Result<(), ()> { - while let Some(ref mut node) = root { - match value.cmp(&node.value) { - Ordering::Equal => return Err(()), - Ordering::Less => root = &mut node.left, - Ordering::Greater => root = &mut node.right, - } - } - *root = Some(Box::new(Node::new(value))); - - Ok(()) - } - - fn recursive_insert(&mut self, value: T) -> Result<(), ()> { - match value.cmp(&self.value) { - Ordering::Equal => Err(()), - Ordering::Less => match self.left { - None => { - self.left = Some(Box::from(Node::new(value))); - Ok(()) - } - Some(ref mut node) => node.recursive_insert(value), - }, - Ordering::Greater => match self.right { - None => { - self.right = Some(Box::from(Node::new(value))); - Ok(()) - } - Some(ref mut node) => node.recursive_insert(value), - }, - } - } - - fn iterative_contains(mut root: &HeapNode, value: &T) -> bool { - while let Some(current) = root { - match value.cmp(¤t.value) { - Ordering::Equal => return true, - Ordering::Less => root = ¤t.left, - Ordering::Greater => root = ¤t.right, - } - } - - false - } - - fn recursive_contains(&self, value: &T) -> bool { - match value.cmp(&self.value) { - Ordering::Equal => true, - Ordering::Less => match self.left { - None => false, - Some(ref node) => node.recursive_contains(value), - }, - Ordering::Greater => match self.right { - None => false, - Some(ref node) => node.recursive_contains(value), - }, - } - } - - fn iterative_retrieve<'a>(mut root: &'a HeapNode, value: &T) -> Option<&'a T> { - while let Some(current) = root { - match value.cmp(¤t.value) { - Ordering::Equal => return Some(¤t.value), - Ordering::Less => root = ¤t.left, - Ordering::Greater => root = ¤t.right, - } - } - - None - } - - fn recursive_retrieve(&self, value: &T) -> Option<&T> { - match value.cmp(&self.value) { - Ordering::Equal => Some(&self.value), - Ordering::Less => match self.left { - None => None, - Some(ref node) => node.recursive_retrieve(value), - }, - Ordering::Greater => match self.right { - None => None, - Some(ref node) => node.recursive_retrieve(value), - }, - } - } - - fn iterative_retrieve_as_mut<'a>( - mut root: &'a mut HeapNode, - value: &T, - ) -> Option<&'a mut T> { - while let Some(current) = root { - match value.cmp(¤t.value) { - Ordering::Equal => return Some(&mut current.value), - Ordering::Less => root = &mut current.left, - Ordering::Greater => root = &mut current.right, - } - } - - None - } - - fn recursive_retrieve_as_mut(&mut self, value: &T) -> Option<&mut T> { - match value.cmp(&self.value) { - Ordering::Equal => Some(&mut self.value), - Ordering::Less => match self.left { - None => None, - Some(ref mut node) => node.recursive_retrieve_as_mut(value), - }, - Ordering::Greater => match self.right { - None => None, - Some(ref mut node) => node.recursive_retrieve_as_mut(value), - }, - } - } - - fn iterative_height(root: &HeapNode) -> isize { - let mut height = -1; - let mut queue = VecDeque::new(); - queue.push_front(root); - - while !queue.is_empty() { - let mut size = queue.len(); - while size > 0 { - let current = queue.pop_front().as_ref().unwrap().as_ref().unwrap(); - if current.left.is_some() { - queue.push_back(¤t.left); - } - if current.right.is_some() { - queue.push_back(¤t.right); - } - size -= 1; - } - height += 1; - } - - height - } - - fn recursive_height(root: &HeapNode) -> isize { - match root { - None => -1, - Some(node) => { - 1 + max( - Node::recursive_height(&node.left), - Node::recursive_height(&node.right), - ) - } - } - } - - fn iterative_remove(mut root: &mut HeapNode, value: &T) -> Result<(), ()> { - while let Some(ref mut current) = root { - match value.cmp(¤t.value) { - Ordering::Less => root = &mut root.as_mut().unwrap().left, - Ordering::Greater => root = &mut root.as_mut().unwrap().right, - Ordering::Equal => { - match (current.left.as_mut(), current.right.as_mut()) { - (None, None) => *root = None, - (Some(_), None) => *root = current.left.take(), - (None, Some(_)) => *root = current.right.take(), - (Some(_), Some(_)) => { - root.as_mut().unwrap().value = - Node::iterative_remove_min(&mut current.right).unwrap() - } - } - - return Ok(()); - } - } - } - - Err(()) - } - - fn recursive_remove(root: &mut HeapNode, value: &T) -> Result<(), ()> { - if let Some(ref mut node) = root { - return match value.cmp(&node.value) { - Ordering::Less => Node::recursive_remove(&mut node.left, value), - Ordering::Greater => Node::recursive_remove(&mut node.right, value), - Ordering::Equal => { - match (&node.left, &node.right) { - (None, None) => *root = None, - (Some(_), None) => *root = node.left.take(), - (None, Some(_)) => *root = node.right.take(), - (Some(_), Some(_)) => { - node.value = Node::recursive_remove_min(&mut node.right).unwrap() - } - } - - Ok(()) - } - }; - } - - Err(()) - } - - fn iterative_min(mut root: &HeapNode) -> Option<&T> { - while let Some(current) = root { - if current.left.is_none() { - return Some(¤t.value); - } - root = ¤t.left; - } - - None - } - - fn recursive_min(&self) -> Option<&T> { - match &self.left { - None => Some(&self.value), - Some(node) => node.recursive_min(), - } - } - - fn iterative_max(mut root: &HeapNode) -> Option<&T> { - while let Some(current) = root { - if current.right.is_none() { - return Some(¤t.value); - } - root = ¤t.right; - } - - None - } - - fn recursive_max(&self) -> Option<&T> { - match &self.right { - None => Some(&self.value), - Some(node) => node.recursive_max(), - } - } - - fn iterative_remove_min(mut root: &mut HeapNode) -> Option { - if root.is_some() { - while root.as_ref().unwrap().left.is_some() { - root = &mut root.as_mut().unwrap().left - } - - let node = root.take().unwrap(); - *root = node.right; - return Some(node.value); - } - - None - } - - fn recursive_remove_min(root: &mut HeapNode) -> Option { - if root.as_ref().unwrap().left.is_some() { - Node::recursive_remove_min(&mut root.as_mut().unwrap().left) - } else { - let node = root.take().unwrap(); - *root = node.right; - Some(node.value) - } - } - - fn iterative_remove_max(mut root: &mut HeapNode) -> Option { - if root.is_some() { - while root.as_ref().unwrap().right.is_some() { - root = &mut root.as_mut().unwrap().right - } - - let node = root.take().unwrap(); - *root = node.left; - return Some(node.value); - } - - None - } - - fn recursive_remove_max(root: &mut HeapNode) -> Option { - if root.as_ref().unwrap().right.is_some() { - Node::recursive_remove_max(&mut root.as_mut().unwrap().right) - } else { - let node = root.take().unwrap(); - *root = node.left; - Some(node.value) - } - } - - fn iterative_pre_order_vec(node: &HeapNode) -> Vec<&T> { - let mut elements = Vec::new(); - let mut stack = vec![node.as_ref()]; - - while let Some(current) = stack.pop().unwrap_or(None) { - elements.push(¤t.value); - if current.right.is_some() { - stack.push(current.right.as_ref()); - } - if current.left.is_some() { - stack.push(current.left.as_ref()); - } - } - - elements - } - - fn recursive_pre_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { - if let Some(ref node) = node { - elements.push(&node.value); - Node::recursive_pre_order_vec(&node.left, elements); - Node::recursive_pre_order_vec(&node.right, elements); - } - } - - fn iterative_in_order_vec(mut root: &HeapNode) -> Vec<&T> { - let mut elements = Vec::new(); - let mut stack = Vec::new(); - - while !stack.is_empty() || root.is_some() { - if root.is_some() { - stack.push(root); - root = &root.as_ref().unwrap().left; - } else { - let node = stack.pop().unwrap(); - elements.push(&node.as_ref().unwrap().value); - root = &node.as_ref().unwrap().right; - } - } - - elements - } - - fn recursive_in_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { - if let Some(ref node) = node { - Node::recursive_in_order_vec(&node.left, elements); - elements.push(&node.value); - Node::recursive_in_order_vec(&node.right, elements); - } - } - - fn iterative_post_order_vec(root: &HeapNode) -> Vec<&T> { - let mut elements = Vec::new(); - let mut stack_one = vec![root]; - let mut stack_two = vec![]; - - while let Some(node) = stack_one.pop().unwrap_or(&None) { - if node.left.is_some() { - stack_one.push(&node.left); - } - if node.right.is_some() { - stack_one.push(&node.right); - } - stack_two.push(node); - } - - while let Some(node) = stack_two.pop() { - elements.push(&node.value); - } - - elements - } - - fn recursive_post_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { - if let Some(ref node) = node { - Node::recursive_post_order_vec(&node.left, elements); - Node::recursive_post_order_vec(&node.right, elements); - elements.push(&node.value); - } - } - - fn iterative_level_order_vec(root: &HeapNode) -> Vec<&T> { - let mut elements = Vec::new(); - let mut deque = VecDeque::new(); - deque.push_front(root.as_ref()); - - while let Some(current) = deque.pop_front().unwrap_or(None) { - elements.push(¤t.value); - if current.left.is_some() { - deque.push_back(current.left.as_ref()); - } - if current.right.is_some() { - deque.push_back(current.right.as_ref()); - } - } - - elements - } - - fn recursive_level_order_vec<'a>(root: &'a HeapNode, elements: &mut Vec<&'a T>) { - let height = Node::recursive_height(root); - for i in 1..=height + 1 { - Node::recursive_current_level(root, elements, i); - } - } - - fn recursive_current_level<'a>(root: &'a HeapNode, elements: &mut Vec<&'a T>, level: isize) { - if root.is_some() { - match level.cmp(&1) { - Ordering::Less => {} - Ordering::Equal => elements.push(&root.as_ref().unwrap().value), - Ordering::Greater => { - Node::recursive_current_level( - &root.as_ref().unwrap().left, - elements, - level - 1, - ); - Node::recursive_current_level( - &root.as_ref().unwrap().right, - elements, - level - 1, - ); - } - } - } - } - - fn iterative_consume_pre_order_vec(node: HeapNode) -> Vec { - let mut elements = Vec::new(); - let mut stack = vec![node]; - - while let Some(current) = stack.pop().unwrap_or(None) { - elements.push(current.value); - if current.right.is_some() { - stack.push(current.right); - } - if current.left.is_some() { - stack.push(current.left); - } - } - - elements - } - - fn recursive_consume_pre_order_vec(node: HeapNode, elements: &mut Vec) { - if let Some(node) = node { - elements.push(node.value); - Node::recursive_consume_pre_order_vec(node.left, elements); - Node::recursive_consume_pre_order_vec(node.right, elements); - } - } - - fn iterative_consume_in_order_vec(root: HeapNode) -> Vec { - let mut elements = Vec::new(); - let mut stack = vec![root]; - - while !stack.is_empty() { - if let Some(mut current) = stack.pop().unwrap() { - if current.left.is_some() { - let left_node = current.left.take(); - stack.push(Some(current)); - stack.push(left_node); - } else { - let right_node = current.right.take(); - elements.push(current.value); - stack.push(right_node); - } - } - } - - elements - } - - fn recursive_consume_in_order_vec(node: HeapNode, elements: &mut Vec) { - if let Some(node) = node { - Node::recursive_consume_in_order_vec(node.left, elements); - elements.push(node.value); - Node::recursive_consume_in_order_vec(node.right, elements); - } - } - - fn iterative_consume_post_order_vec(root: HeapNode) -> Vec { - let mut elements = Vec::new(); - let mut stack_one = vec![root]; - let mut stack_two = vec![]; - - while let Some(mut node) = stack_one.pop().unwrap_or(None) { - if let Some(left_node) = node.left.take() { - stack_one.push(Some(left_node)); - } - if let Some(right_node) = node.right.take() { - stack_one.push(Some(right_node)); - } - stack_two.push(node); - } - - while let Some(node) = stack_two.pop() { - elements.push(node.value); - } - - elements - } - - fn recursive_consume_post_order_vec(node: HeapNode, elements: &mut Vec) { - if let Some(node) = node { - Node::recursive_consume_post_order_vec(node.left, elements); - Node::recursive_consume_post_order_vec(node.right, elements); - elements.push(node.value); - } - } - - fn iterative_consume_level_order_vec(root: HeapNode) -> Vec { - let mut elements = Vec::new(); - let mut deque = VecDeque::new(); - deque.push_front(root); - - while let Some(current) = deque.pop_front().unwrap_or(None) { - elements.push(current.value); - if current.left.is_some() { - deque.push_back(current.left); - } - if current.right.is_some() { - deque.push_back(current.right); - } - } - - elements - } - - fn recursive_consume_level_order_vec(root: HeapNode, elements: &mut Vec) { - let height = Node::recursive_height(&root); - for i in 0..height + 1 { - // SAFETY: this is sound because dealloc_boxes ensures that the elements don't - // get dropped again - unsafe { Node::write_level_into_vec(&root, elements, i) }; - } - Node::dealloc_boxes(root); - } - - /// # Safety - /// - /// The caller must ensure that the values contained in the heap are not dropped again. - /// - /// Otherwise this could lead to a double free. - unsafe fn write_level_into_vec(root: &HeapNode, elements: &mut Vec, level: isize) { - if let Some(node) = root { - if level == 0 { - // "move" the value without actually moving - let element = std::ptr::read(&node.value); - elements.push(element); - } else { - Node::write_level_into_vec(&node.left, elements, level - 1); - Node::write_level_into_vec(&node.right, elements, level - 1); - } - } - } - - fn dealloc_boxes(root: HeapNode) { - if let Some(node) = root { - // move out of the box by de-referencing to drop it and destructure the `Node` - let Node { value, left, right } = *node; - // ensure that the value is not dropped again by forgetting it - std::mem::forget(value); - Node::dealloc_boxes(left); - Node::dealloc_boxes(right); - } - } } \ No newline at end of file diff --git a/src/node.rs b/src/node.rs new file mode 100644 index 0000000..0241cb7 --- /dev/null +++ b/src/node.rs @@ -0,0 +1,569 @@ +use std::cmp::{max, Ordering}; +use std::collections::VecDeque; + +pub(crate) type HeapNode = Option>>; + +#[derive(Debug)] +pub(crate) struct Node { + value: T, + left: HeapNode, + right: HeapNode, +} + +impl Node { + pub(crate) fn new(value: T) -> Node { + Node { + value, + left: None, + right: None, + } + } + + pub(crate) fn iterative_insert(mut root: &mut HeapNode, value: T) -> Result<(), ()> { + while let Some(ref mut node) = root { + match value.cmp(&node.value) { + Ordering::Equal => return Err(()), + Ordering::Less => root = &mut node.left, + Ordering::Greater => root = &mut node.right, + } + } + *root = Some(Box::new(Node::new(value))); + + Ok(()) + } + + pub(crate) fn recursive_insert(&mut self, value: T) -> Result<(), ()> { + match value.cmp(&self.value) { + Ordering::Equal => Err(()), + Ordering::Less => match self.left { + None => { + self.left = Some(Box::from(Node::new(value))); + Ok(()) + } + Some(ref mut node) => node.recursive_insert(value), + }, + Ordering::Greater => match self.right { + None => { + self.right = Some(Box::from(Node::new(value))); + Ok(()) + } + Some(ref mut node) => node.recursive_insert(value), + }, + } + } + + pub(crate) fn iterative_contains(mut root: &HeapNode, value: &T) -> bool { + while let Some(current) = root { + match value.cmp(¤t.value) { + Ordering::Equal => return true, + Ordering::Less => root = ¤t.left, + Ordering::Greater => root = ¤t.right, + } + } + + false + } + + pub(crate) fn recursive_contains(&self, value: &T) -> bool { + match value.cmp(&self.value) { + Ordering::Equal => true, + Ordering::Less => match self.left { + None => false, + Some(ref node) => node.recursive_contains(value), + }, + Ordering::Greater => match self.right { + None => false, + Some(ref node) => node.recursive_contains(value), + }, + } + } + + pub(crate) fn iterative_retrieve<'a>(mut root: &'a HeapNode, value: &T) -> Option<&'a T> { + while let Some(current) = root { + match value.cmp(¤t.value) { + Ordering::Equal => return Some(¤t.value), + Ordering::Less => root = ¤t.left, + Ordering::Greater => root = ¤t.right, + } + } + + None + } + + pub(crate) fn recursive_retrieve(&self, value: &T) -> Option<&T> { + match value.cmp(&self.value) { + Ordering::Equal => Some(&self.value), + Ordering::Less => match self.left { + None => None, + Some(ref node) => node.recursive_retrieve(value), + }, + Ordering::Greater => match self.right { + None => None, + Some(ref node) => node.recursive_retrieve(value), + }, + } + } + + pub(crate) fn iterative_retrieve_as_mut<'a>( + mut root: &'a mut HeapNode, + value: &T, + ) -> Option<&'a mut T> { + while let Some(current) = root { + match value.cmp(¤t.value) { + Ordering::Equal => return Some(&mut current.value), + Ordering::Less => root = &mut current.left, + Ordering::Greater => root = &mut current.right, + } + } + + None + } + + pub(crate) fn recursive_retrieve_as_mut(&mut self, value: &T) -> Option<&mut T> { + match value.cmp(&self.value) { + Ordering::Equal => Some(&mut self.value), + Ordering::Less => match self.left { + None => None, + Some(ref mut node) => node.recursive_retrieve_as_mut(value), + }, + Ordering::Greater => match self.right { + None => None, + Some(ref mut node) => node.recursive_retrieve_as_mut(value), + }, + } + } + + pub(crate) fn iterative_height(root: &HeapNode) -> isize { + let mut height = -1; + let mut queue = VecDeque::new(); + queue.push_front(root); + + while !queue.is_empty() { + let mut size = queue.len(); + while size > 0 { + let current = queue.pop_front().as_ref().unwrap().as_ref().unwrap(); + if current.left.is_some() { + queue.push_back(¤t.left); + } + if current.right.is_some() { + queue.push_back(¤t.right); + } + size -= 1; + } + height += 1; + } + + height + } + + pub(crate) fn recursive_height(root: &HeapNode) -> isize { + match root { + None => -1, + Some(node) => { + 1 + max( + Node::recursive_height(&node.left), + Node::recursive_height(&node.right), + ) + } + } + } + + pub(crate) fn iterative_remove(mut root: &mut HeapNode, value: &T) -> Result<(), ()> { + while let Some(ref mut current) = root { + match value.cmp(¤t.value) { + Ordering::Less => root = &mut root.as_mut().unwrap().left, + Ordering::Greater => root = &mut root.as_mut().unwrap().right, + Ordering::Equal => { + match (current.left.as_mut(), current.right.as_mut()) { + (None, None) => *root = None, + (Some(_), None) => *root = current.left.take(), + (None, Some(_)) => *root = current.right.take(), + (Some(_), Some(_)) => { + root.as_mut().unwrap().value = + Node::iterative_remove_min(&mut current.right).unwrap() + } + } + + return Ok(()); + } + } + } + + Err(()) + } + + pub(crate) fn recursive_remove(root: &mut HeapNode, value: &T) -> Result<(), ()> { + if let Some(ref mut node) = root { + return match value.cmp(&node.value) { + Ordering::Less => Node::recursive_remove(&mut node.left, value), + Ordering::Greater => Node::recursive_remove(&mut node.right, value), + Ordering::Equal => { + match (&node.left, &node.right) { + (None, None) => *root = None, + (Some(_), None) => *root = node.left.take(), + (None, Some(_)) => *root = node.right.take(), + (Some(_), Some(_)) => { + node.value = Node::recursive_remove_min(&mut node.right).unwrap() + } + } + + Ok(()) + } + }; + } + + Err(()) + } + + pub(crate) fn iterative_min(mut root: &HeapNode) -> Option<&T> { + while let Some(current) = root { + if current.left.is_none() { + return Some(¤t.value); + } + root = ¤t.left; + } + + None + } + + pub(crate) fn recursive_min(&self) -> Option<&T> { + match &self.left { + None => Some(&self.value), + Some(node) => node.recursive_min(), + } + } + + pub(crate) fn iterative_max(mut root: &HeapNode) -> Option<&T> { + while let Some(current) = root { + if current.right.is_none() { + return Some(¤t.value); + } + root = ¤t.right; + } + + None + } + + pub(crate) fn recursive_max(&self) -> Option<&T> { + match &self.right { + None => Some(&self.value), + Some(node) => node.recursive_max(), + } + } + + pub(crate) fn iterative_remove_min(mut root: &mut HeapNode) -> Option { + if root.is_some() { + while root.as_ref().unwrap().left.is_some() { + root = &mut root.as_mut().unwrap().left + } + + let node = root.take().unwrap(); + *root = node.right; + return Some(node.value); + } + + None + } + + pub(crate) fn recursive_remove_min(root: &mut HeapNode) -> Option { + if root.as_ref().unwrap().left.is_some() { + Node::recursive_remove_min(&mut root.as_mut().unwrap().left) + } else { + let node = root.take().unwrap(); + *root = node.right; + Some(node.value) + } + } + + pub(crate) fn iterative_remove_max(mut root: &mut HeapNode) -> Option { + if root.is_some() { + while root.as_ref().unwrap().right.is_some() { + root = &mut root.as_mut().unwrap().right + } + + let node = root.take().unwrap(); + *root = node.left; + return Some(node.value); + } + + None + } + + pub(crate) fn recursive_remove_max(root: &mut HeapNode) -> Option { + if root.as_ref().unwrap().right.is_some() { + Node::recursive_remove_max(&mut root.as_mut().unwrap().right) + } else { + let node = root.take().unwrap(); + *root = node.left; + Some(node.value) + } + } + + pub(crate) fn iterative_pre_order_vec(node: &HeapNode) -> Vec<&T> { + let mut elements = Vec::new(); + let mut stack = vec![node.as_ref()]; + + while let Some(current) = stack.pop().unwrap_or(None) { + elements.push(¤t.value); + if current.right.is_some() { + stack.push(current.right.as_ref()); + } + if current.left.is_some() { + stack.push(current.left.as_ref()); + } + } + + elements + } + + pub(crate) fn recursive_pre_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { + if let Some(ref node) = node { + elements.push(&node.value); + Node::recursive_pre_order_vec(&node.left, elements); + Node::recursive_pre_order_vec(&node.right, elements); + } + } + + pub(crate) fn iterative_in_order_vec(mut root: &HeapNode) -> Vec<&T> { + let mut elements = Vec::new(); + let mut stack = Vec::new(); + + while !stack.is_empty() || root.is_some() { + if root.is_some() { + stack.push(root); + root = &root.as_ref().unwrap().left; + } else { + let node = stack.pop().unwrap(); + elements.push(&node.as_ref().unwrap().value); + root = &node.as_ref().unwrap().right; + } + } + + elements + } + + pub(crate) fn recursive_in_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { + if let Some(ref node) = node { + Node::recursive_in_order_vec(&node.left, elements); + elements.push(&node.value); + Node::recursive_in_order_vec(&node.right, elements); + } + } + + pub(crate) fn iterative_post_order_vec(root: &HeapNode) -> Vec<&T> { + let mut elements = Vec::new(); + let mut stack_one = vec![root]; + let mut stack_two = vec![]; + + while let Some(node) = stack_one.pop().unwrap_or(&None) { + if node.left.is_some() { + stack_one.push(&node.left); + } + if node.right.is_some() { + stack_one.push(&node.right); + } + stack_two.push(node); + } + + while let Some(node) = stack_two.pop() { + elements.push(&node.value); + } + + elements + } + + pub(crate) fn recursive_post_order_vec<'a>(node: &'a HeapNode, elements: &mut Vec<&'a T>) { + if let Some(ref node) = node { + Node::recursive_post_order_vec(&node.left, elements); + Node::recursive_post_order_vec(&node.right, elements); + elements.push(&node.value); + } + } + + pub(crate) fn iterative_level_order_vec(root: &HeapNode) -> Vec<&T> { + let mut elements = Vec::new(); + let mut deque = VecDeque::new(); + deque.push_front(root.as_ref()); + + while let Some(current) = deque.pop_front().unwrap_or(None) { + elements.push(¤t.value); + if current.left.is_some() { + deque.push_back(current.left.as_ref()); + } + if current.right.is_some() { + deque.push_back(current.right.as_ref()); + } + } + + elements + } + + pub(crate) fn recursive_level_order_vec<'a>(root: &'a HeapNode, elements: &mut Vec<&'a T>) { + let height = Node::recursive_height(root); + for i in 1..=height + 1 { + Node::recursive_current_level(root, elements, i); + } + } + + fn recursive_current_level<'a>(root: &'a HeapNode, elements: &mut Vec<&'a T>, level: isize) { + if root.is_some() { + match level.cmp(&1) { + Ordering::Less => {} + Ordering::Equal => elements.push(&root.as_ref().unwrap().value), + Ordering::Greater => { + Node::recursive_current_level( + &root.as_ref().unwrap().left, + elements, + level - 1, + ); + Node::recursive_current_level( + &root.as_ref().unwrap().right, + elements, + level - 1, + ); + } + } + } + } + + pub(crate) fn iterative_consume_pre_order_vec(node: HeapNode) -> Vec { + let mut elements = Vec::new(); + let mut stack = vec![node]; + + while let Some(current) = stack.pop().unwrap_or(None) { + elements.push(current.value); + if current.right.is_some() { + stack.push(current.right); + } + if current.left.is_some() { + stack.push(current.left); + } + } + + elements + } + + pub(crate) fn recursive_consume_pre_order_vec(node: HeapNode, elements: &mut Vec) { + if let Some(node) = node { + elements.push(node.value); + Node::recursive_consume_pre_order_vec(node.left, elements); + Node::recursive_consume_pre_order_vec(node.right, elements); + } + } + + pub(crate) fn iterative_consume_in_order_vec(root: HeapNode) -> Vec { + let mut elements = Vec::new(); + let mut stack = vec![root]; + + while !stack.is_empty() { + if let Some(mut current) = stack.pop().unwrap() { + if current.left.is_some() { + let left_node = current.left.take(); + stack.push(Some(current)); + stack.push(left_node); + } else { + let right_node = current.right.take(); + elements.push(current.value); + stack.push(right_node); + } + } + } + + elements + } + + pub(crate) fn recursive_consume_in_order_vec(node: HeapNode, elements: &mut Vec) { + if let Some(node) = node { + Node::recursive_consume_in_order_vec(node.left, elements); + elements.push(node.value); + Node::recursive_consume_in_order_vec(node.right, elements); + } + } + + pub(crate) fn iterative_consume_post_order_vec(root: HeapNode) -> Vec { + let mut elements = Vec::new(); + let mut stack_one = vec![root]; + let mut stack_two = vec![]; + + while let Some(mut node) = stack_one.pop().unwrap_or(None) { + if let Some(left_node) = node.left.take() { + stack_one.push(Some(left_node)); + } + if let Some(right_node) = node.right.take() { + stack_one.push(Some(right_node)); + } + stack_two.push(node); + } + + while let Some(node) = stack_two.pop() { + elements.push(node.value); + } + + elements + } + + pub(crate) fn recursive_consume_post_order_vec(node: HeapNode, elements: &mut Vec) { + if let Some(node) = node { + Node::recursive_consume_post_order_vec(node.left, elements); + Node::recursive_consume_post_order_vec(node.right, elements); + elements.push(node.value); + } + } + + pub(crate) fn iterative_consume_level_order_vec(root: HeapNode) -> Vec { + let mut elements = Vec::new(); + let mut deque = VecDeque::new(); + deque.push_front(root); + + while let Some(current) = deque.pop_front().unwrap_or(None) { + elements.push(current.value); + if current.left.is_some() { + deque.push_back(current.left); + } + if current.right.is_some() { + deque.push_back(current.right); + } + } + + elements + } + + pub(crate) fn recursive_consume_level_order_vec(root: HeapNode, elements: &mut Vec) { + let height = Node::recursive_height(&root); + for i in 0..height + 1 { + // SAFETY: this is sound because dealloc_boxes ensures that the elements don't + // get dropped again + unsafe { Node::write_level_into_vec(&root, elements, i) }; + } + Node::dealloc_boxes(root); + } + + /// # Safety + /// + /// The caller must ensure that the values contained in the heap are not dropped again. + /// + /// Otherwise this could lead to a double free. + unsafe fn write_level_into_vec(root: &HeapNode, elements: &mut Vec, level: isize) { + if let Some(node) = root { + if level == 0 { + // "move" the value without actually moving + let element = std::ptr::read(&node.value); + elements.push(element); + } else { + Node::write_level_into_vec(&node.left, elements, level - 1); + Node::write_level_into_vec(&node.right, elements, level - 1); + } + } + } + + fn dealloc_boxes(root: HeapNode) { + if let Some(node) = root { + // move out of the box by de-referencing to drop it and destructure the `Node` + let Node { value, left, right } = *node; + // ensure that the value is not dropped again by forgetting it + std::mem::forget(value); + Node::dealloc_boxes(left); + Node::dealloc_boxes(right); + } + } +}