// Definition for a binary tree node.
function TreeNode(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
// Recursive inorder traversal
function inorderTraversal(root) {
const result = [];
function traverse(node) {
if (node === null) return;
traverse(node.left); // Visit left subtree
result.push(node.val); // Visit root
traverse(node.right); // Visit right subtree
}
traverse(root);
return result;
}
### Iterative Solution
// Iterative inorder traversal
function inorderTraversal(root) {
const result = [];
const stack = [];
let current = root;
while (current !== null || stack.length > 0) {
// Reach the leftmost node of the current node
while (current !== null) {
stack.push(current);
current = current.left;
}
// Current must be null at this point
current = stack.pop();
result.push(current.val); // Visit the node
// We have visited the node and its left subtree. Now, it's right subtree's turn
current = current.right;
}
return result;
}
## Complexity Analysis
### Recursive Approach
- **Time Complexity**: O(n) - We visit each node exactly once.
- **Space Complexity**: O(h) - The height of the tree, due to the call stack.
### Iterative Approach
- **Time Complexity**: O(n) - We visit each node exactly once.
- **Space Complexity**: O(h) - The height of the tree, due to the explicit stack.
## Edge Cases
- An empty tree (root is null).
- A tree with only one node.
- A tree where all nodes are either left children or right children.
### Example Edge Cases
1. **Empty Tree**:
- Input: `[]`
- Output: `[]`
2. **Single Node**:
- Input: `[1]`
- Output: `[1]`
3. **All Left Children**:
- Input: `[3, 2, null, 1]`
- Output: `[1, 2, 3]`
## Testing
To test the solution comprehensively:
1. Test with an empty tree.
2. Test with a single node.
3. Test with a balanced tree.
4. Test with a skewed tree (all left or all right children).
### Example Test Cases
// Test cases
const root1 = new TreeNode(1, null, new TreeNode(2, new TreeNode(3)));
console.log(inorderTraversal(root1)); // [1, 3, 2]
const root2 = null;
console.log(inorderTraversal(root2)); // []
const root3 = new TreeNode(1);
console.log(inorderTraversal(root3)); // [1]
const root4 = new TreeNode(3, new TreeNode(2, new TreeNode(1)));
console.log(inorderTraversal(root4)); // [1, 2, 3]
## Thinking and Problem-Solving Tips
- Break down the problem into smaller parts.
- Understand the traversal order and ensure you follow it.
- Use diagrams to visualize the tree and the traversal process.
- Practice with different types of trees to get comfortable with edge cases.
## Conclusion
Inorder traversal is a fundamental tree traversal technique with various applications. Understanding both recursive and iterative approaches is crucial for solving related problems efficiently. Practice and familiarity with different tree structures will enhance problem-solving skills.
## Additional Resources
- [Binary Tree Traversal](https://en.wikipedia.org/wiki/Tree_traversal)
- [LeetCode - Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/)
- [GeeksforGeeks - Inorder Tree Traversal](https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/)
By mastering these concepts, you will be well-equipped to tackle a wide range of tree-related problems in coding interviews and real-world applications. Happy coding!
Our interactive tutorials and AI-assisted learning will help you master problem-solving skills and teach you the algorithms to know for coding interviews.
Start Coding for FREE