Tree Traversal Preorder Root Left Right in DSA Go - Time & Space Complexity
We want to understand how the time needed to visit all nodes in a tree grows as the tree gets bigger.
Specifically, we ask: How does preorder traversal scale with the number of nodes?
Analyze the time complexity of the following code snippet.
func preorder(root *Node) {
if root == nil {
return
}
fmt.Println(root.value) // Visit root
preorder(root.left) // Traverse left subtree
preorder(root.right) // Traverse right subtree
}
This code visits each node starting from the root, then left child, then right child recursively.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Visiting each node once (printing value).
- How many times: Exactly once per node in the tree.
As the number of nodes grows, the number of visits grows at the same rate.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 visits |
| 100 | 100 visits |
| 1000 | 1000 visits |
Pattern observation: The operations grow linearly with the number of nodes.
Time Complexity: O(n)
This means the time to complete preorder traversal grows directly in proportion to the number of nodes.
[X] Wrong: "Preorder traversal takes more than linear time because it visits nodes multiple times."
[OK] Correct: Each node is visited exactly once, so the total work is proportional to the number of nodes, not more.
Understanding preorder traversal time helps you explain how tree algorithms scale and shows you can analyze recursive code clearly.
"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
- Starting traversal from left child instead of root
Node?Solution
Step 1: Recall preorder traversal order
Preorder visits root first, then left subtree, then right subtree.Step 2: Check function order
func preorder(root *Node) { if root == nil { return } fmt.Println(root.Value) preorder(root.Left) preorder(root.Right) } prints root value first, then recursively visits left and right children, matching preorder.Final Answer:
func preorder(root *Node) { if root == nil { return } fmt.Println(root.Value) preorder(root.Left) preorder(root.Right) } -> Option BQuick Check:
Print root before children calls [OK]
- Printing after recursive calls (postorder)
- Swapping left and right recursive calls
- Missing nil check for root
10
/ \
5 15
/ / \
3 12 20
func preorder(root *Node) {
if root == nil {
return
}
fmt.Print(root.Value, " ")
preorder(root.Left)
preorder(root.Right)
}
Solution
Step 1: Start at root node 10
Print 10, then traverse left subtree.Step 2: Traverse left subtree (5, then 3)
Print 5, then left child 3, which has no children.Step 3: Traverse right subtree (15, 12, 20)
Print 15, then left child 12, then right child 20.Final Answer:
[10, 5, 3, 15, 12, 20] -> Option DQuick Check:
Preorder = Root, Left, Right [OK]
- Mixing preorder with inorder or postorder output
- Visiting right subtree before left
- Skipping leaf nodes
func preorder(root *Node) {
if root == nil {
return
}
preorder(root.Left)
fmt.Print(root.Value, " ")
preorder(root.Right)
}
Solution
Step 1: Analyze print position in code
The root value is printed after preorder(root.Left), so root is visited after left subtree.Step 2: Compare with preorder definition
Preorder requires visiting root first, then left, then right. This code visits left first, then root, then right (inorder).Final Answer:
The root value is printed after left subtree traversal, not before -> Option CQuick Check:
Print root before children for preorder [OK]
- Confusing preorder with inorder traversal
- Ignoring nil check (though present here)
- Thinking print function choice affects traversal order
Solution
Step 1: Understand preorder collection logic
Preorder means add root value first, then traverse left and right subtrees.Step 2: Check each option's order and parameter usage
func preorder(root *Node, result *[]int) { if root == nil { return } *result = append(*result, root.Value) preorder(root.Left, result) preorder(root.Right, result) } appends root value first, then recursively traverses left and right, using pointer to slice to collect values correctly.Final Answer:
func preorder(root *Node, result *[]int) { if root == nil { return } *result = append(*result, root.Value) preorder(root.Left, result) preorder(root.Right, result) } -> Option AQuick Check:
Append root first, use pointer to slice [OK]
- Appending after recursive calls (wrong order)
- Passing slice by value and expecting changes
- Appending right subtree before left subtree
Ready to prove it?
Pass the test and this pattern moves unknown
