← Back to Blog & Downloads
Data StructuresInteractive
Binary Search Tree: Inorder Traversal
Interactive walkthrough of inorder traversal on a binary search tree, with step-by-step visualization of the recursion and call stack.
Inorder DFS
Tree Traversal
// recursive vs iterative - TypeScript implementation
Select Tree
RecursiveCall Stack Approach★ pick this for DFS
speed
// call stack (OS manages this)
current node
-
visited (inorder)
// inorder output
inorder-recursive.ts
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// TypeScript - Recursive interface TreeNode { val: number; left: TreeNode | null; right: TreeNode | null; } function inorderRecursive( node: TreeNode | null, result: number[] = [] ): number[] { if (node === null) return result; inorderRecursive(node.left, result); // ← go LEFT first result.push(node.val); // ← visit ROOT inorderRecursive(node.right, result); // ← then RIGHT return result; }
O(n)
Time
O(h)
Space (call stack)
h=log n
balanced tree
IterativeExplicit Stack Approachgood to know
speed
stack []
empty
current node
-
// inorder output
inorder-iterative.ts
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// TypeScript - Iterative (explicit stack) function inorderIterative( root: TreeNode | null ): number[] { const result: number[] = []; const stack: TreeNode[] = []; // ← we manage this! let current = root; while (current !== null || stack.length > 0) { // push LEFT nodes until we hit null while (current !== null) { stack.push(current); current = current.left; } current = stack.pop()!; // ← backtrack result.push(current.val); // ← visit node current = current.right; // ← go RIGHT } return result; }
O(n)
Time
O(h)
Space (explicit stack)
✓ Safe
no stack overflow
// breadth first search
BFS Level Order Traversal
Unlike DFS which goes deep before wide, BFS visits every node level by level, left to right. Uses a queue (FIFO) instead of a stack (FILO).
DFS Inorder1234567
BFS Level Order4261357
⬇
DFS Stack
LIFO, goes deep before wide
vs
➡
BFS Queue
FIFO, visits level by level
RecursiveLevel-by-Level Recursionavoid for BFS
speed
L0
4
L1
26
L2
1357
current level
-
call depth
-
// level order output
bfs-recursive.ts
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// TypeScript - BFS Recursive // helper: collect one level's nodes function collectLevel( nodes: TreeNode[], result: number[][], depth: number ): void { if (nodes.length === 0) return; // base case // visit all nodes on this level result[depth] = nodes.map(n => n.val); // gather ALL children for the next level const nextLevel: TreeNode[] = []; for (const node of nodes) { if (node.left) nextLevel.push(node.left); if (node.right) nextLevel.push(node.right); } // recurse with next level's nodes collectLevel(nextLevel, result, depth + 1); } function levelOrderRecursive( root: TreeNode | null ): number[][] { if (!root) return []; const result: number[][] = []; collectLevel([root], result, 0); return result; }
⚠BFS is naturally iterative. The recursive version still passes all nodes of a level as an array; there's no single-node recursion like DFS. Stack overflow risk remains for very deep trees.
O(n)
Time
O(w)
Space (level width)
O(h)
call stack depth
IterativeQueue-Driven Approach★ pick this for BFS
speed
L0
4
L1
26
L2
1357
queue [] (FIFO)
—
current level
-
// level order output
bfs-iterative.ts
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// TypeScript - BFS Iterative (preferred) function levelOrderIterative( root: TreeNode | null ): number[][] { if (!root) return []; const result: number[][] = []; const queue: TreeNode[] = [root]; // ← seed with root while (queue.length > 0) { // freeze level size BEFORE processing const levelSize = queue.length; const level: number[] = []; for (let i = 0; i < levelSize; i++) { const node = queue.shift()!; // ← FIFO dequeue level.push(node.val); if (node.left) queue.push(node.left); if (node.right) queue.push(node.right); } result.push(level); } return result; }
01
shift() not pop()
shift() = FIFO (queue front). pop() = LIFO (stack top). Using pop() here gives you DFS, the wrong algorithm entirely.02
Freeze levelSize
Capture
queue.length before the inner loop. As you enqueue children, the queue grows. The snapshot tells you where the current level ends.03
Why iterative wins
BFS is inherently a queue algorithm. The iterative version is cleaner, safer (no call stack), and is the standard solution you'll see in interviews.
04
Enqueue order matters
Always push
left before right. This preserves left-to-right reading order within each level of the output.O(n)
Time
O(w)
Space (queue)
✓ Best
preferred approach