How do you do a level order traversal of a binary tree?
Use a queue that starts with the root. At each step, note how many nodes are in the queue, because that is exactly the number of nodes on the current level. Remove that many nodes, record their values, and enqueue their children.
from collections import deque
class TreeNode:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def level_order(root):
if root is None:
return []
queue = deque([root])
levels = []
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.value)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
levels.append(level)
return levels
tree = TreeNode(1, TreeNode(2, TreeNode(4)), TreeNode(3))
print(level_order(tree))The output is the list 1, then 2 and 3, then 4. The root is alone on the first level, its two children are on the second, and the node with value four is on the third.
The mechanism is the level boundary. The queue holds the not yet processed nodes, and by recording its length before you start popping you know how many belong to this level. The children you enqueue go behind those nodes, so they belong to the next level. The range is evaluated once at the start of the loop, which is exactly why it must be captured rather than recomputed.
The trade-off to name is that this is breadth first traversal, so it uses memory proportional to the width of the tree rather than its depth. For a balanced tree that is half the node count, which is fine, but for a very wide tree it can be large. The depth first traversals use memory proportional to the height instead. The other detail worth stating is that the loop condition is checked against the queue rather than a level count, and the level list is built inside the loop so that the output keeps the level grouping.