BFS
Binary Tree
Level Order Traversal
Tree Formatting
Algorithm

Printing BFS Binary Tree in Level Order with Specific Formatting

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

Breadth-first traversal prints a binary tree level by level, which makes structural patterns easy to inspect. When interviews or debugging tasks ask for specific formatting, the challenge is not BFS itself but predictable output rules. This guide shows a Python implementation that prints each level with customizable formatting.

Core BFS Level-Order Traversal

Use a queue to process nodes in first-in, first-out order. For level formatting, process one queue snapshot at a time.

python
1from collections import deque
2from dataclasses import dataclass
3from typing import Optional
4
5
6@dataclass
7class Node:
8    value: int
9    left: Optional["Node"] = None
10    right: Optional["Node"] = None
11
12
13def bfs_levels(root: Optional[Node]):
14    if root is None:
15        return []
16
17    q = deque([root])
18    levels = []
19
20    while q:
21        level_size = len(q)
22        current = []
23
24        for _ in range(level_size):
25            node = q.popleft()
26            current.append(node.value)
27
28            if node.left is not None:
29                q.append(node.left)
30            if node.right is not None:
31                q.append(node.right)
32
33        levels.append(current)
34
35    return levels

This function returns level data that can be formatted in many ways.

Once levels are collected, formatting becomes a presentation step.

python
1def print_levels(levels):
2    for idx, values in enumerate(levels):
3        joined = " | ".join(str(v) for v in values)
4        print(f"Level {idx}: {joined}")
5
6
7root = Node(
8    10,
9    left=Node(6, Node(4), Node(8)),
10    right=Node(14, Node(12), Node(16)),
11)
12
13levels = bfs_levels(root)
14print_levels(levels)

Example output:

text
Level 0: 10
Level 1: 6 | 14
Level 2: 4 | 8 | 12 | 16

This pattern is easy to read and aligns with many coding challenge requirements.

Include Missing Children Placeholders

Some problems require preserving tree shape with placeholders for missing children.

python
1from collections import deque
2
3
4def bfs_with_nulls(root, max_levels=4):
5    if root is None:
6        return []
7
8    q = deque([root])
9    levels = []
10
11    for _ in range(max_levels):
12        level_size = len(q)
13        current = []
14        has_real_node = False
15
16        for _ in range(level_size):
17            node = q.popleft()
18            if node is None:
19                current.append("null")
20                q.append(None)
21                q.append(None)
22            else:
23                current.append(str(node.value))
24                has_real_node = True
25                q.append(node.left)
26                q.append(node.right)
27
28        if not has_real_node and all(v == "null" for v in current):
29            break
30
31        levels.append(current)
32
33    return levels

Placeholders are useful for serialization debugging and shape-sensitive output checks.

Complexity and Practical Considerations

Time complexity is linear in number of visited nodes. Space complexity is proportional to maximum queue width, which can approach half the node count in broad trees.

For large trees, avoid building huge formatted strings in memory. Stream each level directly to output if possible.

When implementing in interview settings, clarify formatting rules first. Small differences such as delimiter choice or trailing spaces can cause failed automated checks.

Custom Formatting Templates

Many coding tasks require output such as comma-separated values, bracketed levels, or indentation per depth. Keep formatting rules in a dedicated function that accepts a level index and list of values. This separates traversal correctness from display requirements and makes unit tests simpler. For example, you can assert raw level arrays once, then test multiple formatter variants independently. This approach is especially helpful when one algorithm must support both console output and structured logging formats in production tools.

Common Pitfalls

A frequent mistake is mixing DFS recursion with level formatting requirements. DFS can still produce levels, but BFS queue logic is usually simpler and less error-prone for this task.

Another issue is forgetting to snapshot level_size before iterating. Without that boundary, levels can bleed into each other.

Placeholder logic also causes bugs when null expansion never terminates. Add clear stopping rules.

Finally, do not mutate shared queue state from helper functions unless ownership is explicit. Keep traversal state centralized.

Summary

  • BFS with a queue is the standard way to print binary trees in level order.
  • Capture one queue layer at a time for stable per-level formatting.
  • Separate traversal from formatting for flexible output requirements.
  • Use placeholder-aware traversal only when shape preservation is required.
  • Confirm delimiter and spacing rules before finalizing formatted output.

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.