Tree Traversal Preorder Root Left Right in DSA Rust - Time & Space Complexity
We want to understand how long it takes to visit all nodes in a tree using preorder traversal.
How does the time grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
struct Node {
value: i32,
left: Option>,
right: Option>,
}
fn preorder(node: &Option>) {
if let Some(n) = node {
println!("{}", n.value);
preorder(&n.left);
preorder(&n.right);
}
}
This code visits each node in the tree starting from the root, then left child, then right child.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls visiting each node once.
- How many times: Once per node in the tree.
Each node is visited exactly one time, so the work grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 visits |
| 100 | 100 visits |
| 1000 | 1000 visits |
Pattern observation: The number of operations grows linearly with the number of nodes.
Time Complexity: O(n)
This means the time to traverse grows directly in proportion to the number of nodes in the tree.
[X] Wrong: "Preorder traversal takes more time because it visits nodes multiple times."
[OK] Correct: Each node is visited exactly once, so the time grows linearly, not more.
Understanding preorder traversal time helps you explain how tree operations scale, a key skill in many coding interviews.
"What if we changed preorder to inorder traversal? How would the time complexity change?"
Practice
Solution
Step 1: Understand preorder traversal definition
Preorder traversal visits the root node first, then the left subtree, and finally the right subtree.Step 2: Match the order with options
Root, Left, Right matches the order Root, Left, Right exactly.Final Answer:
Root, Left, Right -> Option AQuick Check:
Preorder = Root, Left, Right [OK]
- Confusing preorder with inorder or postorder
- Swapping left and right subtree order
- Thinking traversal starts with left child
Node with left and right children?Solution
Step 1: Identify preorder traversal steps in code
Preorder visits root first (print value), then left subtree, then right subtree.Step 2: Check each option's order
fn preorder(node: &Option) { if let Some(n) = node { print!("{} ", n.value); preorder(&n.left); preorder(&n.right); } } prints root value first, then recursively visits left and right children, matching preorder.Final Answer:
Print root value first, then left, then right -> Option AQuick Check:
Print root before children = preorder [OK]
- Printing after left subtree (inorder)
- Printing after both subtrees (postorder)
- Swapping left and right recursive calls
10
/ \
5 15
/ / \
3 12 20
Solution
Step 1: Start at root and visit nodes in preorder
Visit root 10, then left subtree: 5, then 3. Then right subtree: 15, then 12, then 20.Step 2: Write traversal sequence
Sequence is 10, 5, 3, 15, 12, 20 matching [10, 5, 3, 15, 12, 20].Final Answer:
[10, 5, 3, 15, 12, 20] -> Option DQuick Check:
Preorder visits root first, then left, then right [OK]
- Listing nodes in inorder or postorder
- Mixing left and right subtree order
- Skipping leaf nodes
fn preorder(node: &Option) {
if let Some(n) = node {
preorder(&n.left);
print!("{} ", n.value);
preorder(&n.right);
}
}
Solution
Step 1: Analyze order of operations in function
The function calls preorder on left child first, then prints root value, then calls preorder on right child.Step 2: Identify traversal type from order
This order is Left, Root, Right which is inorder traversal, not preorder.Final Answer:
Print happens after left subtree, so it's inorder traversal -> Option CQuick Check:
Preorder prints root first, this prints after left [OK]
- Confusing preorder with inorder traversal
- Ignoring order of print statement
- Assuming recursion order alone defines traversal
Solution
Step 1: Understand preorder collection order
Preorder means add root value first, then collect left subtree, then right subtree.Step 2: Check which code pushes root value first
fn preorder_collect(node: &Option, vals: &mut Vec<i32>) { if let Some(n) = node { vals.push(n.value); preorder_collect(&n.left, vals); preorder_collect(&n.right, vals); } } pushes root value before recursive calls, matching preorder.Final Answer:
Push root value first, then left, then right -> Option BQuick Check:
Push root before children for preorder collection [OK]
- Pushing after left subtree (inorder)
- Pushing after both subtrees (postorder)
- Swapping left and right recursion order
Ready to prove it?
Pass the test and this pattern moves unknown
