Binary Trees
Tree Traversal
Level Order
Programming Algorithms
Data Structures

Print Specific nodes at a every level calculated by a given function

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

If you need to print only selected nodes from each level of a tree, the cleanest approach is usually a level-order traversal combined with a function that decides which index or indices to keep at that level. The tree traversal gives you the nodes level by level, and the function adds the selection rule without changing the traversal itself.

Start with Level-Order Traversal

Because the requirement is "at every level," breadth-first traversal is the natural fit. A queue lets you visit the tree one level at a time and collect the nodes that belong to the current depth.

Here is a simple binary-tree setup in Python:

python
1from collections import deque
2
3
4class Node:
5    def __init__(self, value, left=None, right=None):
6        self.value = value
7        self.left = left
8        self.right = right

Now a basic level-order traversal:

python
1def levels(root):
2    if root is None:
3        return
4
5    queue = deque([root])
6
7    while queue:
8        level_size = len(queue)
9        current = []
10
11        for _ in range(level_size):
12            node = queue.popleft()
13            current.append(node)
14
15            if node.left is not None:
16                queue.append(node.left)
17            if node.right is not None:
18                queue.append(node.right)
19
20        yield current

This separates the tree into actual level lists. Once you have that, selecting specific nodes becomes much easier.

Let a Function Choose the Index per Level

Suppose a function tells you which node index to print at each level. For example, maybe you want:

  • the first node at level 0
  • the second node at level 1
  • the third node at level 2

That can be represented by a function of the level number:

python
def target_index(level):
    return level

Then the printing logic becomes:

python
1def print_selected_nodes(root, index_func):
2    for level_number, nodes in enumerate(levels(root)):
3        idx = index_func(level_number)
4
5        if 0 <= idx < len(nodes):
6            print(nodes[idx].value)

Example tree:

python
1root = Node(
2    1,
3    Node(2, Node(4), Node(5)),
4    Node(3, Node(6), Node(7))
5)
6
7print_selected_nodes(root, lambda level: level)

This prints node 1 at level 0, node 3 at level 1, and node 7 at level 2 because the function chooses index 0, then 1, then 2.

The nice part is that the selection rule is now separate from the traversal logic.

Support More Flexible Selection Rules

Sometimes the function should depend on more than the level number. Maybe it should look at the level width too, such as "print the middle node of each level."

python
1def print_selected_nodes(root, index_func):
2    for level_number, nodes in enumerate(levels(root)):
3        idx = index_func(level_number, len(nodes))
4
5        if 0 <= idx < len(nodes):
6            print(nodes[idx].value)
7
8
9print_selected_nodes(root, lambda level, width: width // 2)

This prints the middle node at each level.

You can also generalize further so the function returns multiple indices:

python
1def print_multiple_selected_nodes(root, indices_func):
2    for level_number, nodes in enumerate(levels(root)):
3        indices = indices_func(level_number, len(nodes))
4
5        for idx in indices:
6            if 0 <= idx < len(nodes):
7                print(nodes[idx].value)
8
9
10print_multiple_selected_nodes(root, lambda level, width: [0, width - 1])

That prints the leftmost and rightmost nodes of every level when those indices are valid.

Keep the Selection Function Safe

The traversal is usually not the difficult part. The real edge cases live in the function that calculates which node to print.

If the function returns an index outside the level bounds, the code must handle it gracefully. That is why the bounds check is important:

python
if 0 <= idx < len(nodes):
    print(nodes[idx].value)

This avoids crashes on shallow or uneven levels, especially when the chosen function grows faster than the level width.

The same principle applies if the function returns multiple indices. Treat the selection rule as untrusted until you validate it against the size of the current level.

Common Pitfalls

The biggest mistake is trying to solve this with depth-first traversal first. You can do it, but the logic becomes harder because the problem is naturally organized by levels.

Another issue is assuming the selection function will always return a valid index. Functions based on level number often exceed the number of nodes available at some depth.

Developers also sometimes mix up node values and node positions. The selection function should usually choose an index in the current level, not a value in the tree.

Finally, if the tree is not binary but a general tree with many children, the same level-order idea still works. Only the child-enqueue logic changes.

Summary

  • A level-order traversal is the natural basis for selecting nodes at each tree level.
  • Keep traversal and selection logic separate by passing a function that chooses indices.
  • The selection function can depend on level number, level width, or both.
  • Always validate returned indices against the number of nodes at the current level.
  • If you need multiple nodes per level, let the function return a list of indices instead of one value.

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.