Skip to content

Instantly share code, notes, and snippets.

@SkymanOne
Last active February 20, 2022 16:17
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 SkymanOne/a9c07e38cd2fb35c09fc68a3de0dc434 to your computer and use it in GitHub Desktop.
Save SkymanOne/a9c07e38cd2fb35c09fc68a3de0dc434 to your computer and use it in GitHub Desktop.
Basic binary tree in rust
//alias a complex type for cleaner code
pub type Link = Option<Box<Node>>;
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Node {
value: i8,
left_node: Link,
right_node: Link,
}
impl Node {
fn new(value: i8) -> Self {
Node {
value,
left_node: None,
right_node: None,
}
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct BinaryTree {
root: Link,
depth: i8,
number_of_nodes: i8,
}
impl BinaryTree {
///init empty tree
pub fn new() -> Self {
Self {
root: None,
depth: 0,
number_of_nodes: 0,
}
}
///init tree from value
pub fn from_value(value: i8) -> Self {
let node = Node::new(value);
Self {
root: Some(Box::new(node)),
depth: 1,
number_of_nodes: 1,
}
}
///non-recursive & linear implementation of tree insertion
pub fn insert_linear(&mut self, value: i8) -> bool {
let mut temp = &mut self.root;
let new_node = Node::new(value);
loop {
if let Some(node) = temp {
match node.value.cmp(&new_node.value) {
std::cmp::Ordering::Less => {
temp = &mut node.right_node;
}
std::cmp::Ordering::Equal => {
return false;
}
std::cmp::Ordering::Greater => {
temp = &mut node.left_node;
}
}
} else {
*temp = Some(Box::new(new_node));
return true;
}
}
}
///1. entry point to recursive insertion
pub fn insert(&mut self, value: i8) -> bool {
let temp = &mut self.root;
let node = Node::new(value);
Self::insert_internal(Box::new(node), temp)
}
/// 2. internal recursive method that also searches through node,
/// if no node is present with given value, insert a new one
/// can be potentially replace by search
fn insert_internal(node: Box<Node>, current_node: &mut Link) -> bool {
if let Some(tmp) = current_node {
match tmp.value.cmp(&node.value) {
std::cmp::Ordering::Less => {
Self::insert_internal(node, &mut tmp.right_node)
}
std::cmp::Ordering::Equal => {
false
}
std::cmp::Ordering::Greater => {
Self::insert_internal(node, &mut tmp.left_node)
}
}
} else {
*current_node = Some(node);
true
}
}
///non-recursive & linear implementation of tree search
pub fn get_linear(&mut self, value: i8) -> Option<&Node> {
let mut current_node = &self.root;
while let Some(node) = current_node {
match node.value.cmp(&value) {
std::cmp::Ordering::Less => {
current_node = &node.right_node;
}
std::cmp::Ordering::Equal => {
return Some(node);
}
std::cmp::Ordering::Greater => {
current_node = &node.left_node;
}
}
}
None
}
///1. entry point to recursive method to get locate a node
pub fn get(&mut self, value: i8) -> Option<&Node> {
Self::get_internal(value, &self.root)
}
///2. internal method that recursively searches for corresponding node
fn get_internal(value: i8, current_node: &Link) -> Option<&Node> {
if let Some(node) = current_node {
match node.value.cmp(&value) {
std::cmp::Ordering::Less => return Self::get_internal(value, &node.right_node),
std::cmp::Ordering::Equal => {
return Some(node);
}
std::cmp::Ordering::Greater => return Self::get_internal(value, &node.left_node),
}
}
None
}
}
fn main() {
let mut b_tree = BinaryTree::from_value(1);
b_tree.insert_linear(4);
b_tree.insert_linear(3);
b_tree.insert_linear(5);
let r = b_tree.get_linear(4).unwrap().left_node.as_ref().unwrap();
println!("{}", r.value);
let t = b_tree.insert_linear(6);
let t = b_tree.insert_linear(6);
println!("{}", t);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment