gemla/tree/mod.rs
1//! An unbalanced binary tree type where each node has an optional left and right child.
2//!
3//! # Examples
4//!
5//! ```
6//! use gemla::btree;
7//!
8//! // Tree with 2 nodes, one root node and one on the left side
9//! let mut t = btree!(1, btree!(2),);
10//!
11//! assert_eq!(t.height(), 2);
12//! assert_eq!(t.left.unwrap().val, 2);
13//! assert_eq!(t.right, None);
14//!
15//! t.right = Some(Box::new(btree!(3)));
16//! assert_eq!(t.right.unwrap().val, 3);
17//! ```
18
19use serde::{Deserialize, Serialize};
20use std::cmp::max;
21
22/// An unbalanced binary tree type where each node has an optional left and right child.
23///
24/// # Examples
25///
26/// ```
27/// use gemla::btree;
28///
29/// // Tree with 2 nodes, one root node and one on the left side
30/// let mut t = btree!(1, btree!(2),);
31///
32/// assert_eq!(t.height(), 2);
33/// assert_eq!(t.left.unwrap().val, 2);
34/// assert_eq!(t.right, None);
35///
36/// t.right = Some(Box::new(btree!(3)));
37/// assert_eq!(t.right.unwrap().val, 3);
38/// ```
39#[derive(Default, Serialize, Deserialize, PartialEq, Debug)]
40pub struct Tree<T> {
41 /// The value stored in this node
42 pub val: T,
43
44 /// The left child node, if any
45 pub left: Option<Box<Tree<T>>>,
46
47 /// The right child node, if any
48 pub right: Option<Box<Tree<T>>>,
49}
50
51/// Short-hand for constructing Trees. `btree!` takes 3 arguments, the first being the
52/// value of the root node, and the other two being child nodes. The last two arguments are
53/// optional.
54///
55/// ```
56/// use gemla::tree::*;
57/// use gemla::btree;
58///
59/// # fn main() {
60/// // A tree with two child nodes.
61/// let t = btree!(1, btree!(2), btree!(3));
62/// assert_eq!(t,
63/// Tree::new(1,
64/// Some(Box::new(Tree::new(2, None, None))),
65/// Some(Box::new(Tree::new(3, None, None)))));
66///
67/// // A tree with only a left node.
68/// let t_left = btree!(1, btree!(2),);
69/// assert_eq!(t_left,
70/// Tree::new(1,
71/// Some(Box::new(Tree::new(2, None, None))),
72/// None));
73///
74/// // A tree with only a right node.
75/// let t_right = btree!(1, , btree!(3));
76/// assert_eq!(t_right,
77/// Tree::new(1,
78/// None,
79/// Some(Box::new(Tree::new(3, None, None)))));
80///
81/// // A tree with no child nodes.
82/// let t_single = btree!(1);
83/// assert_eq!(t_single,
84/// Tree::new(1,
85/// None,
86/// None));
87/// # }
88/// ```
89#[macro_export]
90macro_rules! btree {
91 ($val:expr, $l:expr, $r:expr) => {
92 $crate::tree::Tree::new($val, Some(Box::new($l)), Some(Box::new($r)))
93 };
94 ($val:expr, , $r:expr) => {
95 $crate::tree::Tree::new($val, None, Some(Box::new($r)))
96 };
97 ($val:expr, $l:expr,) => {
98 $crate::tree::Tree::new($val, Some(Box::new($l)), None)
99 };
100 ($val:expr) => {
101 $crate::tree::Tree::new($val, None, None)
102 };
103}
104
105impl<T> Tree<T> {
106 /// Constructs a new [`Tree`] object
107 ///
108 /// # Examples
109 ///
110 /// ```
111 /// use gemla::tree::*;
112 ///
113 /// let t = Tree::new(1, None, None);
114 /// assert_eq!(t, Tree {
115 /// val: 1,
116 /// left: None,
117 /// right: None
118 /// });
119 /// ```
120 pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> {
121 Tree { val, left, right }
122 }
123
124 /// Obtains the height of the longest branch in a [`Tree`]
125 ///
126 /// # Examples
127 ///
128 /// ```
129 /// use gemla::tree::*;
130 /// use gemla::btree;
131 ///
132 /// let t =
133 /// btree!("a",
134 /// btree!("aa",
135 /// btree!("aaa"),),
136 /// btree!("ab"));
137 /// assert_eq!(t.height(), 3);
138 /// ```
139 pub fn height(&self) -> usize {
140 match (self.left.as_ref(), self.right.as_ref()) {
141 (Some(l), Some(r)) => max(l.height(), r.height()) + 1,
142 (Some(l), None) => l.height() + 1,
143 (None, Some(r)) => r.height() + 1,
144 _ => 1,
145 }
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_new() {
155 assert_eq!(
156 Tree::new(30, None, Some(Box::new(Tree::new(20, None, None)))),
157 Tree {
158 val: 30,
159 left: None,
160 right: Some(Box::new(Tree {
161 val: 20,
162 left: None,
163 right: None,
164 })),
165 }
166 );
167 }
168
169 #[test]
170 fn test_height() {
171 assert_eq!(1, btree!(1).height());
172
173 assert_eq!(3, btree!(1, btree!(2), btree!(2, btree!(3),)).height());
174 }
175}