Skip to content

Instantly share code, notes, and snippets.

@JoshuaGross
Created April 5, 2020 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshuaGross/8557d20b986be3aa023f69a80581aaef to your computer and use it in GitHub Desktop.
Save JoshuaGross/8557d20b986be3aa023f69a80581aaef to your computer and use it in GitHub Desktop.
Rust binary tree + printer
use text_io::try_read;
use std::io;
use std::io::prelude::*;
use std::cmp::Ordering;
use std::fmt;
pub enum BST<T: Ord+fmt::Display> {
Leaf {
value: T,
left_child: Box<BST<T>>,
right_child: Box<BST<T>>,
},
Empty,
}
impl <T: Ord+fmt::Display> fmt::Display for BST<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.write_tree(f, 0, "", "", false)
}
}
impl<T: Ord+fmt::Display> BST<T> {
pub fn new() -> Self {
BST::Empty
}
pub fn create(value: T) -> Self {
BST::Leaf {
value,
left_child: Box::new(BST::Empty),
right_child: Box::new(BST::Empty),
}
}
pub fn insert(&mut self, new_value: T) {
match self {
BST::Leaf {
ref value,
ref mut left_child,
ref mut right_child,
} => match new_value.cmp(value) {
Ordering::Less => left_child.insert(new_value),
Ordering::Greater => right_child.insert(new_value),
Ordering::Equal => return,
},
BST::Empty => {
*self = BST::create(new_value);
}
}
}
pub fn is_leaf(&self) -> bool {
match self {
BST::Leaf { value, left_child, right_child } => true,
BST::Empty => false
}
}
pub fn write_tree(&self, f: &mut fmt::Formatter<'_>, level: i32, padding: &str, pointer: &str, has_right_sibling: bool) -> fmt::Result {
match self {
BST::Leaf {
ref value,
ref left_child,
ref right_child,
} => {
if level > 0 {
write!(f, "\n");
write!(f, "{}", padding);
write!(f, "{}", pointer);
}
write!(f, "{}", value);
let mut padding_left: String = padding.to_owned();
let mut padding_right: String = padding.to_owned();
if has_right_sibling {
padding_left.push_str("| ");
} else {
padding_left.push_str(" ");
}
padding_right.push_str(" ");
let mut pointer_left: String = "".to_string();
let mut pointer_right: String = "".to_string();
if right_child.is_leaf() {
pointer_left.push_str("├──");
} else {
pointer_left.push_str("└──");
}
pointer_right.push_str("└──");
left_child.write_tree(f, level + 1, &padding_left, &pointer_left, right_child.is_leaf());
right_child.write_tree(f, level + 1, &padding_right, &pointer_right, false)
},
BST::Empty => {
write!(f, "")
}
}
}
}
fn main() {
let mut done = false;
let mut tree: BST<i32> = BST::new();
while !done {
print!("> ");
io::stdout().flush();
let ir: Result<i32, _> = try_read!();
if ir.is_err() {
done = true;
} else {
let i:i32 = ir.unwrap();
if i < 0 {
done = true
} else {
tree.insert(i);
println!("Entered number: {}", i);
println!("New tree:\n{}", tree);
}
}
}
println!("Done.");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment