Level order traversal line by line

Last Updated : 2 Apr, 2026

Given a Binary Tree, the task is to print the nodes level-wise, each level on a new line.

Example:

Input:

Output:
1
2 3
4 5

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(n^2) Time and O(n) Space

  • Compute Height of the Tree
  • Print nodes of every level from 1 to height by calling a function with given level
  • A recursive function is used to print nodes at a given level where we pass level - 1 in the recursive calls and the base case is to print the node when level is 1.
C++
#include <iostream>
using namespace std;

class Node {
  public:
    int data;
    Node *left, *right;

    Node(int key) {
        data = key;
        left = nullptr;  
        right = nullptr; 
    }
};

// Print nodes at a given level
void printLevel(Node *root, int level, vector<int> &levelNodes) {
    if (root == nullptr)
        return;
    if (level == 1) {
        levelNodes.push_back(root->data);
    }
    else if (level > 1) {
        printLevel(root->left, level - 1, levelNodes);
        printLevel(root->right, level - 1, levelNodes);
    }
}

// Compute the "height" of a tree -- the number of
// nodes along the longest path from the root node
// down to the farthest leaf node.
int height(Node *node) {
    if (node == nullptr)
        return 0;

    // Compute the height of each subtree
    int lheight = height(node->left);
    int rheight = height(node->right);

    // Use the larger one without the ternary operator
    if (lheight > rheight) {
        return lheight + 1;
    }
    else {
        return rheight + 1;
    }
}

// Function to return level order traversal as 
// a vector of vectors
vector<vector<int>> levelOrder(Node *root) {
    vector<vector<int>> result;
    int h = height(root);
    for (int i = 1; i <= h; i++) {
        vector<int> levelNodes;
        printLevel(root, i, levelNodes);
        result.push_back(levelNodes);
    }
    return result;
}

int main() {

    // Binary Tree Representation
    //
    //       1
    //     /   \
    //    2     3
    //   / \
    //  4   5

    Node *root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);

    vector<vector<int>> result = levelOrder(root);
    for (const auto &level : result) {
        for (int val : level) {
            cout << val << " ";
        }
        cout << endl;
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

class Node {
    int data;
    Node left, right;

    Node(int key) {
        data = key;
        left = null;
        right = null;
    }
}

class GfG {
  
    // Compute the "height" of a tree -- the number of
    // nodes along the longest path from the root node
    // down to the farthest leaf node.
    static int height(Node node) {
        if (node == null)
            return 0;
        else {
          
            // compute the height of each subtree
            int lheight = height(node.left);
            int rheight = height(node.right);

            // use the larger one
            return Math.max(lheight, rheight) + 1;
        }
    }

    static void printLevel(Node root, int level,
                                List<Integer> levelNodes) {
        if (root == null)
            return;
        if (level == 1)
            levelNodes.add(root.data);
        else if (level > 1) {
            printLevel(root.left, level - 1, levelNodes);
            printLevel(root.right, level - 1, levelNodes);
        }
    }

    // Function to return level order traversal as a list of
    // lists
    static List<List<Integer> > levelOrder(Node root) {
        List<List<Integer> > result = new ArrayList<>();
        int h = height(root);
        for (int i = 1; i <= h; i++) {
            List<Integer> levelNodes = new ArrayList<>();
            printLevel(root, i, levelNodes);
            result.add(levelNodes);
        }
        return result;
    }

    public static void main(String[] args) {

        // Binary Tree Representation
        //
        //       1
        //     /   \
        //    2     3
        //   / \
        //  4   5

        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
      
        List<List<Integer> > result = levelOrder(root);

        for (List<Integer> level : result) {
            for (int val : level) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}
Python
class Node:
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None

def height(node):
    if node is None:
        return 0
    else:
      
        # compute the height of each subtree
        lheight = height(node.left)
        rheight = height(node.right)

        # use the larger one
        return (lheight + 1) if lheight > rheight else (rheight + 1)

def printLevel(root, level, levelNodes):
    if root is None:
        return
    if level == 1:
        levelNodes.append(root.data)
    elif level > 1:
        printLevel(root.left, level - 1, levelNodes)
        printLevel(root.right, level - 1, levelNodes)

def levelOrder(root):
    result = []
    h = height(root)
    for i in range(1, h + 1):
        levelNodes = []
        printLevel(root, i, levelNodes)
        result.append(levelNodes)
    return result

# Binary Tree Representation
#
#       1
#     /   \
#    2     3
#   / \
#  4   5

root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)

result = levelOrder(root)

for level in result:
    for val in level:
        print(val, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int key) {
        data = key;
        left = null;
        right = null;
    }
}

class GfG {
  
    // Compute the "height" of a tree -- the number of
    // nodes along the longest path from the root node
    // down to the farthest leaf node.
    static int Height(Node node) {
        if (node == null)
            return 0;
        else {
          
            // compute the height of each subtree
            int lheight = Height(node.left);
            int rheight = Height(node.right);

            // use the larger one
            return Math.Max(lheight, rheight) + 1;
        }
    }

    static void PrintLevel(Node root, int level, 
                                List<int> levelNodes) {
        if (root == null)
            return;
        if (level == 1)
            levelNodes.Add(root.data);
        else if (level > 1) {
            PrintLevel(root.left, level - 1, levelNodes);
            PrintLevel(root.right, level - 1, levelNodes);
        }
    }

    // Function to return level order traversal 
  	// as a list of lists
    static List<List<int>> LevelOrder(Node root) {
        List<List<int>> result = new List<List<int>>();
        int h = Height(root);
        for (int i = 1; i <= h; i++) {
            List<int> levelNodes = new List<int>();
            PrintLevel(root, i, levelNodes);
            result.Add(levelNodes);
        }
        return result;
    }

    static void Main() {
      
        // Binary Tree Representation
        //
        //       1
        //     /   \
        //    2     3
        //   / \
        //  4   5
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);

        List<List<int>> result = LevelOrder(root);

        foreach (var level in result) {
            foreach (var val in level) {
                Console.Write(val + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
class Node {
    constructor(key) {
        this.data = key;
        this.left = null;
        this.right = null;
    }
}

function height(node) {
    if (node === null) {
        return 0;
    } else {
    
        // compute the height of each subtree 
        const lheight = height(node.left);
        const rheight = height(node.right);

        // use the larger one 
        return Math.max(lheight, rheight) + 1;
    }
}

function printLevel(root, level, levelNodes) {
    if (root === null) {
        return;
    }
    if (level === 1) {
        levelNodes.push(root.data);
    } else if (level > 1) {
        printLevel(root.left, level - 1, levelNodes);
        printLevel(root.right, level - 1, levelNodes);
    }
}

function levelOrder(root) {
    const result = [];
    const h = height(root);
    for (let i = 1; i <= h; i++) {
        const levelNodes = [];
        printLevel(root, i, levelNodes);
        result.push(levelNodes);
    }
    return result;
}

// Binary Tree Representation
//
//       1
//     /   \
//    2     3
//   / \
//  4   5

// driver code
const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);

const traversal = levelOrder(root);
for (const level of traversal) {
    console.log(level.join(" "));
}

Output
1 
2 3 
4 5 

[Expected Approach] Using Queue – O(n) Time and O(n) Space

  • If we take a closer look at the working of standard level order traversal, we can notice that after processing a every iteration, we have the nodes of the next level in the queue. Why? because when we do level order traversal, we push children of the current node after processing it.
  • Before beginning the standard queue based loop, we get the size of the queue to count the number of nodes and then run a loop to print those many nodes followed by a newline.
C++
#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = nullptr;
        right = nullptr;
    }
};

// Function to do level order traversal and return a 2D vector
vector<vector<int>> levelOrder(Node* root) {
    vector<vector<int>> result;
    if (root == nullptr)
        return result;

    // Create an empty queue for level order traversal
    queue<Node*> q;
    q.push(root);

    while (!q.empty()) {
      
        // nodeCount (queue size) indicates number of 
      	// nodes at current level.
        int nodeCount = q.size();
        vector<int> currentLevel;

        for(int i = 0; i < nodeCount; i++) {
            Node* node = q.front();
            q.pop();
            currentLevel.push_back(node->data);

            if (node->left != nullptr)
                q.push(node->left);
            if (node->right != nullptr)
                q.push(node->right);
        }
        result.push_back(currentLevel);
    }

    return result;
}

int main() {
  
    // Binary tree structure:
    //
    //        1
    //       / \
    //      2   3
    //     / \
    //    4   5
  
    Node* root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);

    vector<vector<int>> traversal = levelOrder(root);
    for (const auto& level : traversal) {
        for (int val : level) {
            cout << val << " ";
        }
        cout << endl;
    }
    
    return 0;
}
Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
  
    // Function to do level order traversal and return a 2D list
    static ArrayList<ArrayList<Integer>> levelOrder(Node root) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if (root == null) return result;

        // Create an empty queue for level order traversal
        Queue<Node> q = new LinkedList<>();
        q.add(root);

        while (!q.isEmpty()) {
          
            // nodeCount (queue size) indicates number of
          	// nodes at current level.
            int nodeCount = q.size();
            ArrayList<Integer> currentLevel = new ArrayList<>();

            for(int i = 0; i < nodeCount; i++) {
                Node node = q.poll();
                currentLevel.add(node.data);

                if (node.left != null) q.add(node.left);
                if (node.right != null) q.add(node.right);
            }
            result.add(currentLevel);
        }

        return result;
    }

    public static void main(String[] args) {
      
        // Binary tree structure:
        //
        //        1
        //       / \
        //      2   3
        //     / \
        //    4   5
        //
      
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);

        ArrayList<ArrayList<Integer>> traversal = levelOrder(root); 
        for (ArrayList<Integer> level : traversal) {
            for (int val : level) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}
Python
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

# Function to do level order traversal
# and return a 2D list
def levelOrder(root):
    result = []
    if root is None:
        return result

    # Create an empty queue for level order traversal
    q = [root]

    while q:
      
        # nodeCount (queue size) indicates number 
        # of nodes at current level.
        nodeCount = len(q)
        currentLevel = []

        for i in range(nodeCount):
            node = q.pop(0)
            currentLevel.append(node.data)

            if node.left is not None:
                q.append(node.left)
            if node.right is not None:
                q.append(node.right)

        result.append(currentLevel)

    return result

if __name__ == "__main__":
  
    # Binary tree structure:
    #
    #        1
    #       / \
    #      2   3
    #     / \
    #    4   5
    #
    
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)


    traversal = levelOrder(root)
    for level in traversal:
        for val in level:
            print(val, end=" ")
        print()
C#
using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
  
    // Function to do level order traversal and return a 2D list
    static List<List<int>> LevelOrder(Node root) {
        List<List<int>> result = new List<List<int>>();
        if (root == null) return result;

        // Create an empty queue for level order traversal
        Queue<Node> queue = new Queue<Node>();
        queue.Enqueue(root);

        while (queue.Count > 0) {
          
            // nodeCount (queue size) indicates number of
          	// nodes at current level.
            int nodeCount = queue.Count;
            List<int> currentLevel = new List<int>();

            for(int i = 0; i < nodeCount; i++) {
                Node node = queue.Dequeue();
                currentLevel.Add(node.data);

                if (node.left != null) queue.Enqueue(node.left);
                if (node.right != null) queue.Enqueue(node.right);
            }
            result.Add(currentLevel);
        }

        return result;
    }

    static void Main(string[] args) {
      
		// Binary tree structure:
        //
        //        1
        //       / \
        //      2   3
        //     / \
        //    4   5
      
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);

        List<List<int>> traversal = LevelOrder(root);
        foreach (List<int> level in traversal) {
            foreach (int val in level) {
                Console.Write(val + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Function to do level order traversal and return a 2D array
function levelOrder(root) {
    const result = [];
    if (root === null) return result;

    // Create an empty queue for level order traversal
    const q = [root];

    while (q.length > 0) {
    
        // nodeCount (queue size) indicates number 
        // of nodes at current level.
        const nodeCount = q.length;
        const currentLevel = [];

        for (let i = 0; i < nodeCount; i++) {
            const node = q.shift();
            currentLevel.push(node.data);

            if (node.left !== null) q.push(node.left);
            if (node.right !== null) q.push(node.right);
        }

        result.push(currentLevel);
    }

    return result;
}

// Binary tree structure:
//        1
//       / \
//      2   3
//     / \
//    4   5

const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);

const traversal = levelOrder(root);
for (const level of traversal) {
    console.log(level.join(" "));
}

Output
1 
2 3 
4 5 

Related articles:

Comment