🌳 Inorder Traversal in Binary Tree (BT) #94
Given the root of a Binary Tree, perform Inorder Traversal and return the sequence of visited nodes.
👉 Inorder Traversal Order:
Left → Root → Right
-
It’s one of the three fundamental DFS traversals
-
In a Binary Search Tree, inorder traversal gives sorted order 🔥
-
Helps in:
- Tree validation (BST check)
- Expression tree evaluation
- Tree flattening & transformations
Think of it like:
“Check the left side first, process yourself, then check the right side” Very polite traversal 😌
Binary Tree:
4 2 1 7 5 8 3 6
At every node:
- Completely explore the left subtree
- Visit the current node
- Completely explore the right subtree
This recursive definition matches the tree’s structure perfectly. Trees and recursion are basically best friends 🤝.
There’s no real “brute force” traversal, but beginners often:
- Recompute paths
- Use unnecessary arrays
- Or simulate recursion badly
Still ends up O(N), but messy and inefficient.
👉 Better approach: use recursion or a stack cleanly.
We’ll cover three versions:
- Recursive (most intuitive)
- Iterative using Stack (interview favorite)
- Morris Traversal (O(1) space, big-brain mode 🧠)
Use recursion to:
- Traverse left
- Process root
- Traverse right
If root is NULL:
return
Inorder(root.left)
Visit root
Inorder(root.right)
void inorder(Node* root, vector<int>& result) {
if (!root) return;
inorder(root->left, result);
result.push_back(root->val);
inorder(root->right, result);
}- Tree is recursive by nature
- Each node is visited exactly once
- Very readable and clean ✨
- Time: O(N)
- Space: O(H) (H = height of tree, recursion stack)
🔥 Interviewers LOVE this one
We manually simulate recursion using a stack:
- Go as left as possible
- Process node
- Move right
Like retracing steps in a maze 🗺️
-
Initialize empty stack
-
Set
current = root -
While
current != NULLor stack not empty:- Push all left nodes
- Pop stack, process node
- Move to right child
vector<int> inorderTraversal(Node* root) {
vector<int> result;
stack<Node*> st;
Node* curr = root;
while (curr != nullptr || !st.empty()) {
while (curr != nullptr) {
st.push(curr);
curr = curr->left;
}
curr = st.top();
st.pop();
result.push_back(curr->val);
curr = curr->right;
}
return result;
}- Time: O(N)
- Space: O(H) stack
If recursion is banned ❌ → This is your go-to solution.
“I bend the tree, but I don’t break it.” – Morris Traversal (probably)
- Temporarily create threads to predecessor
- Avoid stack & recursion
- Restore tree after traversal
-
If left child is NULL → visit node, move right
-
Else:
- Find inorder predecessor
- Create temporary link
- Traverse left
-
Remove link after use
vector<int> inorderMorris(Node* root) {
vector<int> result;
Node* curr = root;
while (curr) {
if (!curr->left) {
result.push_back(curr->val);
curr = curr->right;
} else {
Node* prev = curr->left;
while (prev->right && prev->right != curr)
prev = prev->right;
if (!prev->right) {
prev->right = curr;
curr = curr->left;
} else {
prev->right = nullptr;
result.push_back(curr->val);
curr = curr->right;
}
}
}
return result;
}- Time: O(N)
- Space: O(1) 😎
- Harder to implement
- Easy to mess up
- Use only when space is critical
| Tree | Output |
|---|---|
| Empty tree | [] |
| Single node | [1] |
| Skewed left | increasing order |
| Skewed right | same as preorder |
| BST | Sorted output |
- Inorder traversal of BST = sorted array
- Stack size depends on tree height
- Morris traversal modifies tree temporarily
- Validate Binary Search Tree
- Kth smallest element in BST
- Recover BST
- Flatten binary tree
- Inorder successor / predecessor
Because BST property ensures:
Left < Root < Right
So inorder gives sorted values 📈
- Recursive → clarity
- Iterative → preferred
- Morris → flex 💪 (only if asked)
Yes, Morris Traversal
Traversal order is same, but meaning differs Only BST guarantees sorted output.
Avoid recursion → use iterative
Inorder = Left → Root → Right
Recursive = clean
Iterative = stack
Morris = O(1) space
BST inorder = sorted