#[derive(Debug)]
struct BinaryTreeNode<T: Ord + Copy> {
value: T,
left: BinaryTree<T>,
right: BinaryTree<T>,
}
/// A container storing a set of values, using a binary tree.
///
/// If the same value is added multiple times, it is only stored once.
#[derive(Debug)]
pub struct BinaryTree<T: Ord + Copy>(Option<Box<BinaryTreeNode<T>>>);
impl<T: Ord + Copy> BinaryTree<T> {
fn new() -> Self {
Self(None)
}
fn insert(&mut self, value: T) {
match &mut self.0 {
None => {
self.0 = Some(Box::new(BinaryTreeNode {
value,
left: BinaryTree::new(),
right: BinaryTree::new(),
}));
}
Some(ref mut n) => {
if value < n.value {
n.left.insert(value);
} else if value > n.value {
n.right.insert(value);
}
}
}
}
fn has(&self, value: T) -> bool {
match &self.0 {
None => false,
Some(n) => {
if value == n.value {
true
} else if value < n.value {
n.left.has(value)
} else {
n.right.has(value)
}
}
}
}
fn len(&self) -> usize {
match &self.0 {
None => 0,
Some(n) => 1 + n.left.len() + n.right.len(),
}
}
}
fn main() {
let mut tree = BinaryTree::new();
tree.insert("foo");
assert_eq!(tree.len(), 1);
tree.insert("bar");
assert!(tree.has("foo"));
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn len() {
let mut tree = BinaryTree::new();
assert_eq!(tree.len(), 0);
tree.insert(2);
assert_eq!(tree.len(), 1);
tree.insert(1);
assert_eq!(tree.len(), 2);
tree.insert(2); // not a unique item
assert_eq!(tree.len(), 2);
}
#[test]
fn has() {
let mut tree = BinaryTree::new();
fn check_has(tree: &BinaryTree<i32>, exp: &[bool]) {
let got: Vec<bool> = (0..exp.len()).map(|i| tree.has(i as i32)).collect();
assert_eq!(&got, exp);
}
check_has(&tree, &[false, false, false, false, false]);
tree.insert(0);
check_has(&tree, &[true, false, false, false, false]);
tree.insert(4);
check_has(&tree, &[true, false, false, false, true]);
tree.insert(4);
check_has(&tree, &[true, false, false, false, true]);
tree.insert(3);
check_has(&tree, &[true, false, false, true, true]);
}
#[test]
fn unbalanced() {
let mut tree = BinaryTree::new();
for i in 0..100 {
tree.insert(i);
}
assert_eq!(tree.len(), 100);
assert!(tree.has(50));
}
}