Tree Traversal Postorder Left Right Root in DSA C++ - 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 look at postorder traversal, which visits left child, then right child, then the node itself.
Analyze the time complexity of the following code snippet.
void postorderTraversal(Node* root) {
if (root == nullptr) return;
postorderTraversal(root->left);
postorderTraversal(root->right);
std::cout << root->value << " ";
}
This code visits every node in the tree in postorder: left subtree, right subtree, then the node itself.
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 once, so the work grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The time grows linearly as the tree size increases.
Time Complexity: O(n)
This means the time to complete the traversal grows directly in proportion to the number of nodes.
[X] Wrong: "Postorder traversal takes more time because it visits nodes multiple times."
[OK] Correct: Each node is visited exactly once, even though the order is left, right, then root. No node is repeated.
Understanding traversal time helps you explain how tree algorithms scale and shows you can reason about recursion and data structures clearly.
"What if we changed the traversal to preorder (root, left, right)? How would the time complexity change?"
Practice
Solution
Step 1: Understand postorder traversal definition
Postorder traversal visits nodes in the order: left subtree first, then right subtree, and finally the root node.Step 2: Match the traversal order to options
Left subtree, Right subtree, Root node correctly lists the order as Left, Right, Root which matches postorder traversal.Final Answer:
Left subtree, Right subtree, Root node -> Option AQuick Check:
Postorder = Left, Right, Root [OK]
- Confusing postorder with preorder or inorder
- Swapping left and right subtree order
- Thinking root is visited first
Node*?Solution
Step 1: Recall postorder traversal steps
Postorder visits left subtree, then right subtree, then root node.Step 2: Check function calls order
void postorder(Node* root) { postorder(root->left); postorder(root->right); visit(root); } calls postorder on left, then right, then visits root, matching postorder traversal.Final Answer:
void postorder(Node* root) { postorder(root->left); postorder(root->right); visit(root); } -> Option DQuick Check:
Left, Right, Root call order = void postorder(Node* root) { postorder(root->left); postorder(root->right); visit(root); } [OK]
- Visiting root before children (preorder)
- Swapping left and right subtree calls
- Missing visit call after recursion
1 / \ 2 3 / \ 4 5
What is the output of a postorder traversal?
Solution
Step 1: Traverse left subtree of root (1)
Left subtree rooted at 2: postorder visits 4, then 5, then 2.Step 2: Traverse right subtree and root
Right subtree is 3 alone, visited next. Finally, root 1 is visited.Final Answer:
[4, 5, 2, 3, 1] -> Option CQuick Check:
Postorder = Left, Right, Root = [4,5,2,3,1] [OK]
- Listing root before children
- Mixing left and right subtree order
- Confusing with preorder or inorder output
void postorder(Node* root) {
if (!root) return;
postorder(root->right);
postorder(root->left);
visit(root);
}Solution
Step 1: Analyze recursive calls order
The code calls postorder on right subtree first, then left subtree, which reverses the correct order.Step 2: Understand correct postorder order
Postorder requires left subtree first, then right subtree, then root visit.Final Answer:
Left and right subtree calls are swapped -> Option AQuick Check:
Left before right in postorder [OK]
- Swapping left and right subtree calls
- Visiting root before children
- Omitting base case check
Solution
Step 1: Confirm traversal order in code
void postorder(Node* root, vector<int>& res) { if (!root) return; postorder(root->left, res); postorder(root->right, res); res.push_back(root->val); } calls postorder on left, then right subtree, then adds root value to vector, matching postorder.Step 2: Check other options for order mistakes
The other options either add the root value too early or swap left and right calls, breaking postorder.Final Answer:
void postorder(Node* root, vector<int>& res) { if (!root) return; postorder(root->left, res); postorder(root->right, res); res.push_back(root->val); } -> Option BQuick Check:
Left, Right, Root push_back order = void postorder(Node* root, vector<int>& res) { if (!root) return; postorder(root->left, res); postorder(root->right, res); res.push_back(root->val); } [OK]
- Pushing root value before children
- Swapping left and right subtree calls
- Forgetting to check for null root
Ready to prove it?
Pass the test and this pattern moves unknown
