Python
Tree Traversal
Data Structures
Algorithms
Programming

Python - Tree traversal question

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

A tree traversal question is usually asking two things: what order should nodes be visited, and how should that order be implemented. In Python, the answer depends on the task. Depth-first traversals are natural for recursive structure, while breadth-first traversal is better when levels matter.

Start With a Simple Tree Model

A binary tree node can be represented with a small class. That is enough to demonstrate the common traversal orders.

python
1from dataclasses import dataclass
2from typing import Optional
3
4
5@dataclass
6class Node:
7    value: int
8    left: Optional["Node"] = None
9    right: Optional["Node"] = None

Example tree:

python
1root = Node(
2    1,
3    left=Node(2, Node(4), Node(5)),
4    right=Node(3, None, Node(6)),
5)

This gives a tree where 1 is the root, 2 and 3 are its children, and the lower nodes form the remaining branches.

Depth-First Traversal Orders

Depth-first traversal visits one branch as far as possible before backtracking. The three common variants differ only in when the current node is processed.

python
1def preorder(node):
2    if node is None:
3        return []
4    return [node.value] + preorder(node.left) + preorder(node.right)
5
6
7def inorder(node):
8    if node is None:
9        return []
10    return inorder(node.left) + [node.value] + inorder(node.right)
11
12
13def postorder(node):
14    if node is None:
15        return []
16    return postorder(node.left) + postorder(node.right) + [node.value]
17
18
19print(preorder(root))
20print(inorder(root))
21print(postorder(root))

For the sample tree, the outputs are:

  • preorder: 1, 2, 4, 5, 3, 6
  • inorder: 4, 2, 5, 1, 3, 6
  • postorder: 4, 5, 2, 6, 3, 1

Inorder is especially important for binary search trees because it yields sorted values.

Breadth-First or Level-Order Traversal

If the question is about visiting nodes one level at a time, use breadth-first traversal with a queue.

python
1from collections import deque
2
3
4def level_order(node):
5    if node is None:
6        return []
7
8    result = []
9    queue = deque([node])
10
11    while queue:
12        current = queue.popleft()
13        result.append(current.value)
14
15        if current.left is not None:
16            queue.append(current.left)
17        if current.right is not None:
18            queue.append(current.right)
19
20    return result
21
22
23print(level_order(root))

For the same tree, level order produces 1, 2, 3, 4, 5, 6.

Recursive vs Iterative Solutions

Many Python answers use recursion because the code matches the tree structure and is easy to read. That is fine for interviews, teaching, and moderate tree depth.

For very deep trees, iterative solutions can be safer because Python recursion has a depth limit. An iterative preorder traversal uses an explicit stack.

python
1def preorder_iterative(node):
2    if node is None:
3        return []
4
5    result = []
6    stack = [node]
7
8    while stack:
9        current = stack.pop()
10        result.append(current.value)
11
12        if current.right is not None:
13            stack.append(current.right)
14        if current.left is not None:
15            stack.append(current.left)
16
17    return result
18
19
20print(preorder_iterative(root))

The stack pushes the right child first so the left child is processed first on the next loop iteration.

How To Choose the Right Traversal

Use preorder when you need to process a node before its descendants, such as serializing a tree structure. Use inorder when tree ordering matters, especially in a binary search tree. Use postorder when children must be handled before parents, such as deleting a tree or computing bottom-up values. Use level order when the problem talks about distance from the root, shortest unweighted path by levels, or printing the tree one row at a time.

A lot of tree traversal questions become easy once you translate the problem statement into one of those four access patterns.

Common Pitfalls

The most common bug is forgetting the base case for None, which causes attribute errors when the traversal reaches a missing child.

Another issue is using recursion on a very deep tree and hitting Python's recursion limit. If the tree can be highly unbalanced, prefer an iterative approach.

Developers also sometimes choose inorder on a tree that is not a binary search tree and then expect sorted output. Inorder only gives sorted values when the tree already satisfies binary search tree ordering.

Finally, be clear about whether the question wants a list of visited values, a generator, printed output, or some aggregated result. Those are different interfaces even if the traversal order is the same.

Summary

  • Tree traversal means visiting nodes in a defined order.
  • The main orders are preorder, inorder, postorder, and level order.
  • Recursive implementations are concise, but iterative ones avoid recursion-depth problems.
  • Pick the traversal based on when the current node should be processed.
  • Clarify the required output before writing the traversal function.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.