// Tree Preorder โ 99 Problems #37
// Construct a binary tree from its preorder and inorder sequences.
#[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))
}
}
/// Preorder traversal: root, left, right.
fn preorder<T: Clone>(tree: &Tree<T>) -> Vec<T> {
match tree {
Tree::Leaf => vec![],
Tree::Node(l, v, r) => {
let mut result = vec![v.clone()];
result.extend(preorder(l));
result.extend(preorder(r));
result
}
}
}
/// Inorder traversal: left, root, right.
fn inorder<T: Clone>(tree: &Tree<T>) -> Vec<T> {
match tree {
Tree::Leaf => vec![],
Tree::Node(l, v, r) => {
let mut result = inorder(l);
result.push(v.clone());
result.extend(inorder(r));
result
}
}
}
/// Reconstruct tree from preorder and inorder sequences.
fn build_from_preorder_inorder<T: PartialEq + Clone>(pre: &[T], ino: &[T]) -> Tree<T> {
if pre.is_empty() || ino.is_empty() {
return Tree::leaf();
}
let root = pre[0].clone();
let root_pos = ino.iter().position(|x| x == &root).expect("root not in inorder");
let left_ino = &ino[..root_pos];
let right_ino = &ino[root_pos + 1..];
let left_pre = &pre[1..1 + left_ino.len()];
let right_pre = &pre[1 + left_ino.len()..];
Tree::node(
build_from_preorder_inorder(left_pre, left_ino),
root,
build_from_preorder_inorder(right_pre, right_ino),
)
}
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();
let pre = preorder(&t);
let ino = inorder(&t);
println!("Preorder: {:?}", pre);
println!("Inorder: {:?}", ino);
let rebuilt = build_from_preorder_inorder(&pre, &ino);
println!("Rebuilt == original: {}", rebuilt == t);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_preorder() {
assert_eq!(preorder(&sample_tree()), vec!['a', 'b', 'd', 'e', 'c']);
}
#[test]
fn test_inorder() {
assert_eq!(inorder(&sample_tree()), vec!['d', 'b', 'e', 'a', 'c']);
}
#[test]
fn test_reconstruct() {
let t = sample_tree();
let pre = preorder(&t);
let ino = inorder(&t);
assert_eq!(build_from_preorder_inorder(&pre, &ino), t);
}
#[test]
fn test_empty() {
let t: Tree<char> = Tree::leaf();
assert_eq!(preorder(&t), vec![]);
assert_eq!(inorder(&t), vec![]);
}
}
(* Tree Preorder *)
(* OCaml 99 Problems #37 *)
(* Implementation for example 37 *)
(* Tests *)
let () =
(* Add tests *)
print_endline "โ OCaml tests passed"