Binary Tree Inorder Traversal
Problem statement
Given the root of a binary tree, return the values of its nodes in in-order: for every node, first everything in its left subtree, then the node itself, then everything in its right subtree.
For a binary search tree, in-order visits the values in ascending order. Trees are written in level order, with null for a missing child.
Examples
Example 1
Input: root = [4, 2, 6, 1, 3, 5]
Output: [1, 2, 3, 4, 5, 6]
Example 2
Input: root = [7, null, 8, 9]
Output: [7, 9, 8]
Explanation: 7 has no left child, so it comes first. Then 8's subtree: its left child 9, then 8.
Hints
Approach
Morris traversal gets rid of the stack. The only reason a stack is needed is to find the way back up to a node after finishing its left subtree. Morris stores that way back inside the tree itself: before going left, it makes the rightmost node of the left subtree (the node's in-order predecessor) point back to the node through its empty right pointer.
- If
curhas no left child, record it and move right. - Otherwise, find the predecessor: go left once, then right as far as possible (stopping if you reach
cur). - If the predecessor's
rightis empty, point it atcurand movecurleft. - If it already points at
cur, the left subtree is done: remove the link, recordcur, and move right.
Every temporary link is removed on the second visit, so the tree is unchanged at the end. Each edge is walked at most a few times, so the time is still linear.
O(n)Space O(1) besides the outputfrom typing import Optional # class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right class Solution: def inorderTraversal(self, root: Optional["TreeNode"]) -> list[int]: out = [] cur = root while cur: if cur.left is None: out.append(cur.val) cur = cur.right continue pred = cur.left # rightmost node of the left subtree while pred.right and pred.right is not cur: pred = pred.right if pred.right is None: pred.right = cur # temporary link back up cur = cur.left else: pred.right = None # left side done: remove the link out.append(cur.val) cur = cur.right return outFollow-up questions
- Write pre-order and post-order traversals iteratively.
- Build a BST iterator with
next()andhasNext()that usesO(h)memory.
Frequently asked questions
It temporarily modifies the tree, so it is not safe if another thread reads the tree at the same time, and an exception mid-walk could leave links behind. In interviews it is a good answer to "can you do it in O(1) space?"; in production the stack version is usually preferred.
Pre-order records the node before its subtrees, post-order after both. Pre-order is what you use to copy or serialise a tree; post-order is what you use when a node needs its children's results first, such as computing sizes or deleting a directory tree.
Traversal order is the core of walking any hierarchy: listing a directory tree, evaluating nested config, or tearing down resources children-first. Being able to switch between recursion and an explicit stack is also practical, since deep hierarchies can exceed recursion limits.