Last active
February 20, 2022 16:17
-
-
Save SkymanOne/a9c07e38cd2fb35c09fc68a3de0dc434 to your computer and use it in GitHub Desktop.
Basic binary tree in rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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