use serde::{Deserialize, Serialize};
use std::cmp::max;
#[derive(Default, Serialize, Deserialize, PartialEq, Debug)]
pub struct Tree<T> {
pub val: T,
pub left: Option<Box<Tree<T>>>,
pub right: Option<Box<Tree<T>>>,
}
#[macro_export]
macro_rules! btree {
($val:expr, $l:expr, $r:expr) => {
$crate::tree::Tree::new($val, Some(Box::new($l)), Some(Box::new($r)))
};
($val:expr, , $r:expr) => {
$crate::tree::Tree::new($val, None, Some(Box::new($r)))
};
($val:expr, $l:expr,) => {
$crate::tree::Tree::new($val, Some(Box::new($l)), None)
};
($val:expr) => {
$crate::tree::Tree::new($val, None, None)
};
}
impl<T> Tree<T> {
pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> {
Tree { val, left, right }
}
pub fn height(&self) -> usize {
match (self.left.as_ref(), self.right.as_ref()) {
(Some(l), Some(r)) => max(l.height(), r.height()) + 1,
(Some(l), None) => l.height() + 1,
(None, Some(r)) => r.height() + 1,
_ => 1,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
assert_eq!(
Tree::new(30, None, Some(Box::new(Tree::new(20, None, None)))),
Tree {
val: 30,
left: None,
right: Some(Box::new(Tree {
val: 20,
left: None,
right: None,
})),
}
);
}
#[test]
fn test_height() {
assert_eq!(1, btree!(1).height());
assert_eq!(3, btree!(1, btree!(2), btree!(2, btree!(3),)).height());
}
}