Android & iPhone apps are coming soon. Log in for a plan and reminders made for you →

Know this before you start: “BFS: level order with a queue”

Breadth-first traversal with a queue

Use a queue to visit a tree level by level. Read the queue's size at the start of each round: that many nodes are exactly one level.

The idea

Breadth-first search visits all nodes at depth 1, then depth 2, and so on. A queue (first in, first out) gives exactly that order: take a node from the front, add its children to the back.

To group nodes by level, note how many are in the queue when a round starts and process exactly that many. Python's collections.deque pops from the front in O(1).

See it step by step

Tree 3 → (9, 20), 20 → (15, 7)

  1. queue [3] → level [3], queue [9, 20]
  2. 2 in the queue → level [9, 20], queue [15, 7]
  3. 2 in the queue → level [15, 7] → done: [[3], [9, 20], [15, 7]]

In code (Python)

from collections import deque

class TreeNode:
    def __init__(self, val, left=None, right=None):
        self.val, self.left, self.right = val, left, right

def levels(root):
    if not root:
        return []
    result, queue = [], deque([root])
    while queue:
        level = []
        for _ in range(len(queue)):       # exactly one level
            node = queue.popleft()
            level.append(node.val)
            for child in (node.left, node.right):
                if child:
                    queue.append(child)
        result.append(level)
    return result

root = TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7)))
print(levels(root))   # [[3], [9, 20], [15, 7]]

O(n) time, O(width) space.

When you'll use it

  • Level order, right side view, minimum depth, zigzag, “closest” or “nearest” in trees.

Common mistakes

  • list.pop(0), which is O(n): use deque.popleft().
  • Reading len(queue) after children were added.

Practise it: Trees

You'll use it again in

Go further