// Collect Leaves โ 99 Problems #31
// Collect the leaves of a binary tree in a list.
#[derive(Debug, PartialEq, Clone)]
enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>),
}
impl<T: Clone> Tree<T> {
fn leaf() -> Self { Tree::Leaf }
fn node(l: Tree<T>, v: T, r: Tree<T>) -> Self {
Tree::Node(Box::new(l), v, Box::new(r))
}
}
fn leaves<T: Clone>(tree: &Tree<T>) -> Vec<T> {
match tree {
Tree::Leaf => vec![],
Tree::Node(l, v, r) => match (l.as_ref(), r.as_ref()) {
(Tree::Leaf, Tree::Leaf) => vec![v.clone()],
_ => {
let mut result = leaves(l);
result.extend(leaves(r));
result
}
},
}
}
/// Tail-recursive version using an explicit stack.
fn leaves_iter<T: Clone>(tree: &Tree<T>) -> Vec<T> {
let mut stack = vec![tree];
let mut result = Vec::new();
while let Some(t) = stack.pop() {
match t {
Tree::Leaf => {}
Tree::Node(l, v, r) => match (l.as_ref(), r.as_ref()) {
(Tree::Leaf, Tree::Leaf) => result.push(v.clone()),
_ => {
// Push right first so left is processed first
stack.push(r);
stack.push(l);
}
},
}
}
result
}
fn sample_tree() -> Tree<char> {
Tree::node(
Tree::node(
Tree::node(Tree::leaf(), 'd', Tree::leaf()),
'b',
Tree::node(Tree::leaf(), 'e', Tree::leaf()),
),
'a',
Tree::node(Tree::leaf(), 'c', Tree::leaf()),
)
}
fn main() {
let t = sample_tree();
println!("Leaves (recursive): {:?}", leaves(&t));
println!("Leaves (iterative): {:?}", leaves_iter(&t));
let single = Tree::node(Tree::leaf(), 'z', Tree::leaf());
println!("Single node leaves: {:?}", leaves(&single));
let empty: Tree<i32> = Tree::leaf();
println!("Empty tree leaves: {:?}", leaves(&empty));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty() {
let t: Tree<i32> = Tree::leaf();
assert_eq!(leaves(&t), vec![]);
}
#[test]
fn test_single_node() {
let t = Tree::node(Tree::leaf(), 42, Tree::leaf());
assert_eq!(leaves(&t), vec![42]);
}
#[test]
fn test_sample_tree() {
// Leaves in left-to-right order: d, e, c
assert_eq!(leaves(&sample_tree()), vec!['d', 'e', 'c']);
}
#[test]
fn test_iter_matches_recursive() {
let t = sample_tree();
assert_eq!(leaves(&t), leaves_iter(&t));
}
}
(* Collect Leaves *)
(* OCaml 99 Problems #31 *)
(* Implementation for example 31 *)
(* Tests *)
let () =
(* Add tests *)
print_endline "โ OCaml tests passed"