Binary trees and level-order traversal
Use a queue to visit nodes by depth
A tournament viewer stores the final match at the root of a binary bracket, with earlier matches underneath it. The display needs the final first, then its semifinals together, then the next round. Following one branch to the bottom would mix those rows.
Level-order traversal keeps the next row in a queue. The match labels don't need sorting; their left-to-right order comes from the bracket itself.
Displaying a bracket one round at a time
Level-order traversal groups tree nodes by depth rather than by lexical name or a depth-first path. A queue or explicit frontier captures the next structural layer. Left children are processed before right children, so each output level retains left-to-right order.
A direct prototype can determine the height and rescan the tree separately for each depth. This repeats visits and can become quadratic on a chain.
Keeping children in the next frontier
At the beginning of a level, all frontier nodes share the same depth. Visit exactly those nodes and collect their children into the next frontier, appending left before right. Do not keep processing children as part of the same level: that flattens deeper nodes into the current output row.
Input nodes are recursive arrays [name, left, right]. A null child is absent, not a node whose name is null. The documented structure has unique names, no shared children and no cycles, so the traversal does not need graph-style visited detection. Read the structure without rewriting child references.
In JavaScript, repeated shift() on a large queue may move many entries. Two level arrays naturally retain O(w) frontier storage. A queue with a head index avoids shifts, but retaining every consumed entry forever uses O(n) storage instead of the promised O(w); reclaim consumed storage or use frontiers.
const root = ["a", ["b", null, null], ["c", null, null]];
const nextFrontier = [root[1], root[2]];
console.log(nextFrontier.map(node => node[0])); // ["b", "c"]
console.log(root[0]); // a: names are data, not ordering keysA wide bracket needs queue space
Final traversal visits each node once: O(n) time and O(w) auxiliary frontier space, excluding returned names, where w is maximum level width. A recursive DFS can also group by depth but uses stack depth and has different failure behavior for a very deep tree. Use BFS when level boundaries themselves are useful, such as breadth summaries or nearest-depth processing.
The bracket stores a tree; a shared or cyclic match graph would also need discovery tracking.
Practice Binary trees and level-order traversal
Implement the exercise in a full-screen workspace, then run its tests.