PrepStack · Markdown HTML

Tree level-order BFS

Tree, BST, and trie · HTML

Formal shape

Initialize queue with root. While nonempty, set level_size=len(queue), pop exactly that many nodes and append their children. This batch has one depth; increment depth after the batch.

Recognition signals

False friends

SignalWhy it is different
Aggregating subtrees into parentsHeight, balance, and diameter are postorder summaries, not naturally layer-based.
Weighted shortest distanceFIFO orders edge count only; unequal nonnegative costs need Dijkstra.
A general graph without deduplicationTrees have unique parents; graph BFS needs visited when enqueuing.

Core invariant

At each round start, the queue contains every node of the current depth and no other depth. After exactly level_size pops, it contains exactly the next depth.

State, transition, and processing order

ItemDefinition
StateA FIFO queue, current depth, and a temporary accumulator for the layer.
TransitionPop one current-level node, update the layer summary, and enqueue each non-null child in stable order.
Frontier / orderUnprocessed current-level nodes followed by already discovered next-level nodes; the frozen size marks their boundary.

Python skeleton

from collections import deque

def levels(root):
    if root is None: return []
    queue, out = deque([root]), []
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left: queue.append(node.left)
            if node.right: queue.append(node.right)
        out.append(level)
    return out

Correctness sketch

  1. Initially the queue contains only the depth-zero root.
  2. A round removes only the frozen level_size nodes, which share one depth by the invariant.
  3. Their non-null children are exactly the next depth and each has one parent, restoring the invariant after the batch.

Complexity

TimeSpaceParameters
O(n)O(w), where w is maximum layer widthn is node count and w the largest number at one depth.

Edge cases

Error patterns

PatternWhy it fails / fix
Letting the loop length grow dynamicallyFreeze the queue size at round start or newly added next-level nodes leak into the current batch.
Returning minimum depth at one missing childA leaf has no children at all, not merely one absent side.
Reversing enqueue order for zigzagThat can alter future layer structure; reverse presentation or write into a deque instead.
Using list.pop(0)Removing the list head is O(n) in Python; use deque.popleft().

Selection and exclusion rules

RelationTemplateBoundary
tree specializationBFS connectivity traversalThe graph is acyclic and output is grouped by levels.
contrastTree recursive aggregationLayer summaries and postorder subtree summaries process opposite structures.

Original micro-example

PartDetail
ResultLayers are [[8],[3,10],[1]], with maximum width two.
SetupRoot 8 has children 3 and 10; node 3 has child 1.
TraceRound queues are [8], then [3,10], then [1].

Recall prompts

My notes