Binary trees are a cornerstone of algorithm interviews, appearing in problems ranging from basic traversal to complex construction challenges. Mastering binary tree techniques is essential for demonstrating algorithmic proficiency. This comprehensive guide systematically covers four traversal methods (preorder, inorder, postorder, level-order), explores both recursive and iterative implementations, and solves classic construction problems (building trees from preorder+inorder and postorder+inorder). We'll also analyze complexity, common pitfalls, optimization techniques, and variant extensions.
Series Navigation
📚 LeetCode Algorithm Masterclass Series (10 Parts):
- Hash Tables (Two Sum, Longest Consecutive, Group Anagrams)
- Two Pointers Techniques (Collision pointers, fast-slow, sliding window)
- Linked List Operations (Reverse, cycle detection, merge)
- Binary Tree Traversal & Recursion (Inorder/Preorder/Postorder, LCA)
- → Binary Tree Traversal & Construction (Pre/In/Post/Level-order, Construction) ← You are here
- Backtracking Algorithms (Permutations, combinations, pruning)
- Dynamic Programming Intro (1D/2D DP, state transition)
- Greedy Algorithms (Interval scheduling, jump game)
- Graph Algorithms (BFS/DFS, topological sort, union-find)
- Bit Manipulation & Math (Bitwise tricks, math problems)
Binary Tree Fundamentals
What is a Binary Tree?
A binary tree is a tree data structure where each node has at most two children, typically referred to as the "left child" and "right child".
Key Properties:
- Each node has at most two children
- Left and right subtrees are ordered (cannot be swapped arbitrarily)
- An empty tree is also a binary tree
Basic Structure:
1 | class TreeNode: |
Types of Binary Trees
Complete Binary Tree: All levels are completely filled except possibly the last level, which is filled from left to right.
Full Binary Tree: Every node has either 0 or 2 children.
Binary Search Tree (BST): For each node, all values in the left subtree < node value < all values in the right subtree.
Balanced Binary Tree: The height difference between left and right subtrees is at most 1.
LeetCode 144: Binary Tree Preorder Traversal
Problem Statement
Given the root of a binary tree, return the
preorder traversal of its nodes' values.
Preorder Order: Root → Left subtree → Right subtree
Example:
- Input:
root = [1,null,2,3] - Output:
[1,2,3]
Constraints:
- The number of nodes in the tree is in the range
[0, 100] -100 <= Node.val <= 100
Problem Analysis
Preorder traversal follows the pattern: visit the root first, then recursively process the left subtree, and finally the right subtree. This is the most intuitive traversal because you always see the root value first.
Use Cases:
- Printing directory structures (print current directory, then subdirectories)
- Copying binary trees (create root first, then copy subtrees)
- Expression tree evaluation (process operator before operands)
Solution Approach
Recursive Approach: Directly implement the definition — visit root, recurse left, recurse right.
Iterative Approach: Use a stack to simulate recursion. Push root onto stack, then loop: pop and visit, push right child first, then left child (order matters because stack is LIFO).
Complexity Analysis
- Time Complexity:
, visiting each node once - Space Complexity:
- Recursive:
, where is tree height (recursion stack depth) - Iterative:
, maximum stack depth equals tree height
- Recursive:
Recursive Implementation
1 | from typing import List, Optional |
Algorithm Principle:
Preorder traversal follows "root-left-right" order. The recursive implementation leverages the function call stack — after finishing the left subtree, execution automatically returns to the previous level to process the right subtree.
Execution Example (tree
[1, null, 2, 3]):
1 | Visit node 1 -> result = [1] |
Iterative Implementation
1 | def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Why Push Right Before Left:
Stacks are Last-In-First-Out (LIFO). To visit the left subtree first, we need the left child to be pushed last, so it pops first.
Execution Example (tree
[1, null, 2, 3]):
1 | Initial: stack = [1], result = [] |
Common Pitfalls
Pitfall 1: Forgetting to Handle Null Nodes
1 | # ❌ Wrong |
Pitfall 2: Wrong Push Order in Iterative Implementation
1 | # ❌ Wrong: Push left then right |
Variant Extension
Variant 1: Morris
Preorder Traversal ( Space)
Morris traversal uses null pointers in the tree to achieve
1 | def preorderTraversal_morris(self, root: Optional[TreeNode]) -> List[int]: |
Complexity Analysis:
- Time Complexity:
, each node visited at most twice - Space Complexity:
, only constant extra space
LeetCode 94: Binary Tree Inorder Traversal
Problem Statement
Given the root of a binary tree, return the
inorder traversal of its nodes' values.
Inorder Order: Left subtree → Root → Right subtree
Example:
- Input:
root = [1,null,2,3] - Output:
[1,3,2]
Problem Analysis
Inorder traversal processes left subtree first, then root, then right subtree. For Binary Search Trees (BST), inorder traversal produces a sorted sequence.
Use Cases:
- BST sorted output: Inorder traversal of BST gives ascending order
- Expression tree evaluation: Inorder traversal of expression tree gives infix expression
- BST validation: Check if inorder result is sorted
Solution Approach
Recursive Approach: Recurse left, visit root, recurse right.
Iterative Approach: Use stack to simulate recursion. Start from root, go left all the way, pushing nodes onto stack. Then pop and visit, turn to right subtree, repeat.
Complexity Analysis
- Time Complexity:
- Space Complexity:
, where is tree height
Recursive Implementation
1 | def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Iterative Implementation
1 | def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Execution Example (tree
[1, null, 2, 3]):
1 | Initial: current = 1, stack = [], result = [] |
Common Pitfall
Pitfall: Forgetting to Turn to Right Subtree
1 | # ❌ Wrong |
LeetCode 145: Binary Tree Postorder Traversal
Problem Statement
Given the root of a binary tree, return the
postorder traversal of its nodes' values.
Postorder Order: Left subtree → Right subtree → Root
Example:
- Input:
root = [1,null,2,3] - Output:
[3,2,1]
Problem Analysis
Postorder traversal processes left and right subtrees first, then visits root. This order is useful when deleting tree nodes, as you need to delete children before parent.
Use Cases:
- Deleting binary tree: Delete subtrees first, then root
- Calculating directory size: Calculate subdirectory sizes first, then total
- Expression tree evaluation: Postorder traversal gives postfix expression (Reverse Polish Notation)
Solution Approach
Recursive Approach: Recurse left, recurse right, visit root.
Iterative Approach: Postorder iteration is more complex. Method 1: Use two stacks, push in "root-right-left" order to stack1, then pop all to stack2, finally pop stack2 to get "left-right-root". Method 2: Use one stack, track visit state for each node (unvisited, left visited, right visited).
Complexity Analysis
- Time Complexity:
- Space Complexity:
Recursive Implementation
1 | def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Iterative Implementation (Two-Stack Method)
1 | def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Why Two-Stack Method Works:
Stack1 traverses in "root-right-left" order (mirror of preorder), pushing to stack2 maintains this order. Popping stack2 reverses it to "left-right-root" (postorder).
Iterative Implementation (Single-Stack Method)
1 | def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: |
Algorithm Visualization: The animation below demonstrates postorder traversal visiting nodes in "left-right-root" order:

LeetCode 102: Binary Tree Level Order Traversal
Problem Statement
Given the root of a binary tree, return the
level order traversal of its nodes' values (i.e., from
left to right, level by level).
Example:
- Input:
root = [3,9,20,null,null,15,7] - Output:
[[3],[9,20],[15,7]]
Problem Analysis
Level-order traversal (BFS) visits nodes level by level from top to bottom, left to right. Requires a queue (FIFO) to maintain order.
Use Cases:
- Printing binary tree: Print tree structure by level
- Finding shortest path: Find shortest path from root to leaf
- Serializing binary tree: Serialize tree structure by level
Solution Approach
Use queue to implement BFS. Enqueue root, then loop: record current level size, dequeue these nodes and visit, enqueue their children.
Complexity Analysis
- Time Complexity:
, each node visited once - Space Complexity:
, where is maximum tree width (maximum queue length)
Implementation
1 | from collections import deque |
Execution Example (tree
[3,9,20,null,null,15,7]):
1 | Initial: queue = [3], result = [] |
Algorithm Visualization: The animation below demonstrates level-order traversal visiting nodes level by level:

Common Pitfall
Pitfall: Forgetting to Record Level Size
1 | # ❌ Wrong |
LeetCode 105: Construct Binary Tree from Preorder and Inorder Traversal
Problem Statement
Given two integer arrays preorder and
inorder where preorder is the preorder
traversal of a binary tree and inorder is the inorder
traversal of the same tree, construct and return the binary tree.
Example:
- Input:
preorder = [3,9,20,15,7],inorder = [9,3,15,20,7] - Output:
[3,9,20,null,null,15,7]
Constraints:
-preorder and inorder consist of unique
values
Problem Analysis
Core Insight:
- First element of preorder is the root
- Find root in inorder, left side is left subtree, right side is right subtree
- Recursively construct left and right subtrees
Key Steps:
- Take first element from preorder as root
- Find root position in inorder
- Based on root position, determine left and right subtree ranges
- Recursively construct left and right subtrees
Solution Approach
Use recursion + hash map to optimize lookup. Hash map stores index of each value in inorder, avoiding linear search each time.
Complexity Analysis
- Time Complexity:
, each node visited once, hash map lookup - Space Complexity:
, hash map + recursion stack
Implementation
1 | def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: |
Index Calculation Details:
Assume preorder = [3,9,20,15,7],
inorder = [9,3,15,20,7]:
1 | Root: 3 (preorder[0]) |
Algorithm Principle
Why Binary Tree is Uniquely Determined:
Preorder tells us root position, inorder tells us left-right subtree division. Combining these uniquely determines tree structure.
Mathematical Proof:
For a tree with
Common Pitfalls
Pitfall 1: Wrong Index Calculation
1 | # ❌ Wrong: Incorrect left subtree size |
Pitfall 2: Forgetting Boundary Conditions
1 | # ❌ Wrong |
LeetCode 106: Construct Binary Tree from Inorder and Postorder Traversal
Problem Statement
Given two integer arrays inorder and
postorder where inorder is the inorder
traversal of a binary tree and postorder is the postorder
traversal of the same tree, construct and return the binary tree.
Example:
- Input:
inorder = [9,3,15,20,7],postorder = [9,15,7,20,3] - Output:
[3,9,20,null,null,15,7]
Problem Analysis
Core Insight:
- Last element of postorder is the root
- Find root in inorder, left side is left subtree, right side is right subtree
- Recursively construct left and right subtrees
Difference from preorder construction: root is at the end of postorder, not the beginning.
Solution Approach
Similar to preorder+inorder construction, but root taken from end of postorder, right subtree range calculated from right to left.
Complexity Analysis
- Time Complexity:
- Space Complexity:
Implementation
1 | def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]: |
Traversal Methods Comparison
| Traversal | Order | Recursive Difficulty | Iterative Difficulty | Typical Applications |
|---|---|---|---|---|
| Preorder | Root-Left-Right | ⭐ | ⭐⭐ | Copy tree, print directory |
| Inorder | Left-Root-Right | ⭐ | ⭐⭐ | BST sorted output, validate BST |
| Postorder | Left-Right-Root | ⭐ | ⭐⭐⭐ | Delete tree, calculate directory size |
| Level-order | Top-bottom, left-right | ⭐⭐ | ⭐⭐ | Print tree, find shortest path |
Memory Mnemonic:
- Preorder: Root first (Root-Left-Right)
- Inorder: Root middle (Left-Root-Right)
- Postorder: Root last (Left-Right-Root)
- Level-order: Level by level (BFS)
Q&A: Common Questions About Binary Tree Traversal
Q1: Why Does Inorder Traversal of BST Produce Sorted Sequence?
A: BST definition: For each node, all values in left subtree < node value < all values in right subtree.
Inorder traversal order is "left-root-right", meaning: 1. First visit all values less than current node (left subtree) 2. Then visit current node 3. Finally visit all values greater than current node (right subtree)
Therefore, inorder traversal of BST naturally produces ascending sequence.
Verification:
1 | # BST: [4,2,6,1,3,5,7] |
Q2: Which is Better: Iterative or Recursive Implementation?
A: Each has pros and cons:
| Aspect | Recursive | Iterative |
|---|---|---|
| Code Simplicity | ✅ Simpler | ❌ More complex |
| Space Complexity | ❌ |
✅ |
| Stack Overflow Risk | ❌ May overflow at great depth | ✅ Controllable |
| Understanding Difficulty | ✅ Intuitive | ❌ Need to understand stack operations |
| Performance | Comparable | Comparable |
Recommendation:
- Interview: Prefer recursion (simpler), rewrite to iterative if interviewer requests
- Production: Use recursion when depth is controllable, use iterative when depth is very large
- Learning: Master both, understand the essence
Q3: How to Choose Traversal Method?
A: Choose based on problem requirements:
Preorder suitable for: - Need to process root before subtrees - Copy tree structure - Print directory structure
Inorder suitable for: - BST operations (search, validate, sorted output) - Expression tree infix expression
Postorder suitable for: - Need to process subtrees before root - Delete tree nodes - Calculate directory size - Expression tree postfix expression
Level-order suitable for: - Need level-by-level processing - Find shortest path - Serialize binary tree
Q4: What are the Advantages of Morris Traversal?
A: Main advantage is
Comparison:
| Method | Space Complexity | Time Complexity | Use Cases |
|---|---|---|---|
| Recursive | General cases | ||
| Iterative + Stack | General cases | ||
| Morris | Space-constrained |
Costs:
- Higher code complexity
- Modifies tree structure (temporary links)
- Not suitable for multi-threaded environments
Recommendation: Unless space is strictly limited, prefer recursive or iterative implementation.
Q5: Why Do We Need Inorder Traversal to Construct Binary Tree?
A: Inorder traversal provides left-right subtree division information.
Why Preorder + Postorder Cannot Uniquely Determine:
Consider two different trees:
1 | Tree 1: 1 Tree 2: 1 |
- Preorder both:
[1, 2] - Postorder both:
[2, 1] - But tree structures differ!
Why Preorder + Inorder Can Uniquely Determine:
- Preorder tells us root position
- Inorder tells us left-right subtree division
- Combining both uniquely determines structure
Mathematical Proof: For
Q6: How to Handle Binary Trees with Duplicate Values?
A: With duplicate values, construction may not be unique.
Problem: If preorder = [1,1,1],
inorder = [1,1,1], cannot uniquely determine tree
structure.
Solutions:
- Assume constraint: Problems usually guarantee unique node values
- If duplicates allowed: Need additional information (e.g., node ID) to distinguish
- Practical application: Usually distinguish by node references rather than values
Q7: Why is
Level-Order Traversal Time Complexity ?
A: Each node is enqueued once and dequeued once.
Analysis:
- Enqueue operations:
times (once per node) - Dequeue operations:
times (once per node) - Visit operations:
times (once per node)
Total operations:
Summary: Key Points of Binary Tree Traversal
Memory Formulas:
- Preorder: Root → Left → Right
- Inorder: Left → Root → Right
- Postorder: Left → Right → Root
- Level-order: BFS, level by level
Memory Mnemonic:
Pre/In/Post determined by root position, Level-order is BFS
Tree construction needs inorder, left-right division depends on it
Practical Checklist:
Common Mistakes to Avoid:
- ✅ Check null nodes in recursion
- ✅ Pay attention to push order in iteration
- ✅ Record level size in level-order traversal
- ✅ Correctly calculate index ranges when constructing tree
By systematically mastering binary tree traversal and construction, you can solve most binary tree-related LeetCode problems. Remember: Recursion is the foundation, iteration is advanced, understanding the essence is key!
- Post title:LeetCode (6): Binary Tree Traversal & Construction
- Post author:Chen Kai
- Create time:2023-06-20 00:00:00
- Post link:https://www.chenk.top/en/leetcode-binary-tree-traversal/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.