Trees
Preorder Traversal
Visit the root before each subtree, producing root-left-right order.
Algorithm
The canonical tree is 4(2(1,3),6(5,7)), so this Rust DSA
implementation can be compared directly with the rest of the DSA track.
Basic Implementation
basic.rs
use std::collections::VecDeque;
struct Node { value: i32, left: Option<Box<Node>>, right: Option<Box<Node>> }
impl Node {
fn new(value: i32) -> Self { Self { value, left: None, right: None } }
fn with(value: i32, left: Node, right: Node) -> Self {
Self { value, left: Some(Box::new(left)), right: Some(Box::new(right)) }
}
}
fn render(node: &Option<Box<Node>>) -> String {
match node {
None => "_".to_string(),
Some(n) => {
if n.left.is_none() && n.right.is_none() { n.value.to_string() }
else { format!("{}({},{})", n.value, render(&n.left), render(&n.right)) }
}
}
}
fn sample_tree() -> Option<Box<Node>> {
Some(Box::new(Node::with(4, Node::with(2, Node::new(1), Node::new(3)), Node::with(6, Node::new(5), Node::new(7)))))
}
fn list_string(values: &[i32]) -> String {
format!("[{}]", values.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
}
fn preorder(node: &Option<Box<Node>>, output: &mut Vec<i32>) { if let Some(n) = node { output.push(n.value); preorder(&n.left, output); preorder(&n.right, output); } }
fn main() { let root = sample_tree(); let mut output = Vec::new(); preorder(&root, &mut output); println!("{}", list_string(&output)); }
Complexity
- Time: O(n)
- Space: O(h) recursion stack
Implementation notes
- Render tree structure explicitly instead of printing node objects.
- The replay highlights the node, traversal state, queue, path, or search cursor that changes at each step.
preorder
Preorder records the current node before visiting left and right subtrees.