use self::BinaryTree::*;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum BinaryTree<T> {
Empty,
NonEmpty(Box<TreeNode<T>>), }
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct TreeNode<T> {
pub element: T,
pub left: BinaryTree<T>,
pub right: BinaryTree<T>,
}
pub struct TreeIter<'a, T: 'a> {
pub unvisited: Vec<&'a TreeNode<T>>, }
impl<'a, T: 'a> TreeIter<'a, T> {
pub fn push_left_edge(&mut self, mut tree: &'a BinaryTree<T>) {
while let NonEmpty(ref node) = *tree {
self.unvisited.push(node); tree = &node.left;
}
}
}
impl<'a, T> Iterator for TreeIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
let node = self.unvisited.pop()?;
self.push_left_edge(&node.right);
Some(&node.element)
}
}
impl<'a, T: 'a> IntoIterator for &'a BinaryTree<T> {
type Item = &'a T; type IntoIter = TreeIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> BinaryTree<T> {
pub fn make_node(value: T, left: BinaryTree<T>, right: BinaryTree<T>) -> BinaryTree<T> {
NonEmpty(Box::new(TreeNode {
element: value,
left,
right,
}))
}
pub fn iter(&self) -> TreeIter<'_, T> {
let mut iter = TreeIter {
unvisited: Vec::new(),
};
iter.push_left_edge(self);
iter
}
}
impl<T: Ord> BinaryTree<T> {
pub fn add(&mut self, value: T) {
match *self {
Empty => {
*self = BinaryTree::make_node(value, Empty, Empty);
}
NonEmpty(ref mut node) => {
if value <= node.element {
node.left.add(value);
} else {
node.right.add(value);
}
}
}
}
}