Open In App

Level order traversal line by line (Using Two Queues)

Last Updated : 01 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

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

Approach:

The idea is to use two queues to traverse in Level order manner. We will insert the first level in first queue and print it and while popping from the first queue insert its left and right nodes into the second queue. Now start printing the second queue and before popping insert its left and right child nodes into the first queue. Continue this process till both the queues become empty.

Step-By-Step Implementation:

  • Start by creating two queues. The first queue is used to store nodes of the current level, while the second queue will hold the nodes of the next level. Begin by inserting the root node into the first queue.
  • While the first queue is not empty, create a temporary container to hold the values of the current level. Dequeue nodes from the first queue and add their values to this container. For each node, enqueue its left and right children into the second queue.
  • After processing all nodes in the first queue, if the container of current level values is not empty, store it in the final result list. This Stores the values of the nodes at the current level.
  • Now, repeat the process for the second queue, dequeue nodes from the second queue and store their values in the same manner, enqueuing their children into the first queue for processing in the next iteration.
  • Continue this alternating process between the two queues until both queues become empty. The result list will then contain the level order traversal of the binary tree.

Below is the implementation of the above approach:

C++
// C++ Program to print level Order 
// traversal of Binary Tree

#include<bits/stdc++.h>
using namespace std;

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

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

// Returns level order traversal as a 2D vector.
vector<vector<int>> levelOrder(Node *root) {
    vector<vector<int>> result;
    if (root == nullptr)
        return result;

    queue<Node *> q1, q2;
    
    q1.push(root);

    // Executing loop till both the queues become empty
    while (!q1.empty() || !q2.empty()) {
        vector<int> currentLevel;
 		
      	// Considering elements of queue q1 and 
        // adding level below it to queue q2
        while (!q1.empty()) {
            Node* curr = q1.front();
            q1.pop();
            currentLevel.push_back(curr->data);

            if (curr->left != nullptr)
                q2.push(curr->left);

            if (curr->right != nullptr)
                q2.push(curr->right);
        }
 	
        // Stroing current level into result
        if (!currentLevel.empty())
            result.push_back(currentLevel);

        currentLevel.clear();

      	// Considering elements of queue q2 and 
        // adding level below it to queue q1
        while (!q2.empty()) {
            Node* curr = q2.front();
            q2.pop();
            currentLevel.push_back(curr->data);
			
            if (curr->left != nullptr)
                q1.push(curr->left);

            if (curr->right != nullptr)
                q1.push(curr->right);
        }
		
      	// Stroing current level into result 
        if (!currentLevel.empty())
            result.push_back(currentLevel);
    }

    return result;
}

int main() {
  
    // Creating the binary tree
	// Binary tree structure:
    //
    //        1
    //       / \
    //      2   3
    //     / \   \
    //    4   5   6

    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);
    root->right->right = new Node(6);

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

    return 0;
}
Java
// Java Program to print level Order 
// traversal of Binary Tree
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 {
  
    // Returns level order traversal as a 2D list.
    static List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null)
            return result;

        Queue<Node> q1 = new LinkedList<>();
        Queue<Node> q2 = new LinkedList<>();
        
        q1.add(root);

        // Executing loop till both the queues become empty
        while (!q1.isEmpty() || !q2.isEmpty()) {
            List<Integer> currentLevel = new ArrayList<>();

            // Process all nodes in the current level from q1
            while (!q1.isEmpty()) {
                Node curr = q1.poll();
                currentLevel.add(curr.data);

                // Add children to q2 for the next level
                if (curr.left != null)
                    q2.add(curr.left);
                if (curr.right != null)
                    q2.add(curr.right);
            }
            
            // Add the current level to the result
            if (!currentLevel.isEmpty())
                result.add(currentLevel);

            currentLevel = new ArrayList<>();

            // Process all nodes in the current level from q2
            while (!q2.isEmpty()) {
                Node curr = q2.poll();
                currentLevel.add(curr.data);

                // Add children to q1 for the next level
                if (curr.left != null)
                    q1.add(curr.left);
                if (curr.right != null)
                    q1.add(curr.right);
            }

            // Add the current level to the result
            if (!currentLevel.isEmpty())
                result.add(currentLevel);
        }

        return result;
    }

    public static void main(String[] args) {
      
        // Binary tree structure:
        //
        //        1
        //       / \
        //      2   3
        //     / \   \
        //    4   5   6
        
        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);
        root.right.right = new Node(6);

        List<List<Integer>> traversal = levelOrder(root);
        for (List<Integer> level : traversal) {
            for (int val : level) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python Program to Print level Order 
# traversal of Binary Tree

from collections import deque

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

# Returns level order traversal as a 2D list.
def levelOrder(root):
    result = []
    if root is None:
        return result

    q1 = deque()
    q2 = deque()
    
    q1.append(root)

    # Executing loop till both the queues become empty
    while q1 or q2:
        currentLevel = []
        
        # Considering elements of queue q1 and 
        # adding level below it to queue q2
        while q1:
            curr = q1.popleft()
            currentLevel.append(curr.data)

            if curr.left is not None:
                q2.append(curr.left)

            if curr.right is not None:
                q2.append(curr.right)

        # Storing current level into result
        if currentLevel:
            result.append(currentLevel)

        currentLevel = []

        # Considering elements of queue q2 and 
        # adding level below it to queue q1
        while q2:
            curr = q2.popleft()
            currentLevel.append(curr.data)
            
            if curr.left is not None:
                q1.append(curr.left)

            if curr.right is not None:
                q1.append(curr.right)
        
        # Storing current level into result 
        if currentLevel:
            result.append(currentLevel)

    return result

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

    traversal = levelOrder(root)
    for level in traversal:
        for val in level:
            print(val, end=" ")
        print()
C#
// C# Program to Print level Order
// traversal of Binary Tree

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 {
  
    // Returns level order traversal as a 2D list.
    static List<List<int>> LevelOrder(Node root) {
        List<List<int>> result = new List<List<int>>();
        if (root == null)
            return result;

        Queue<Node> q1 = new Queue<Node>();
        Queue<Node> q2 = new Queue<Node>();
        
        q1.Enqueue(root);

        // Executing loop till both the queues become empty
        while (q1.Count > 0 || q2.Count > 0) {
            List<int> currentLevel = new List<int>();
            
            // Considering elements of queue q1 and 
            // adding level below it to queue q2
            while (q1.Count > 0) {
                Node curr = q1.Dequeue();
                currentLevel.Add(curr.data);

                if (curr.left != null)
                    q2.Enqueue(curr.left);

                if (curr.right != null)
                    q2.Enqueue(curr.right);
            }
            
            // Storing current level into result
            if (currentLevel.Count > 0)
                result.Add(currentLevel);

            currentLevel = new List<int>();

            // Considering elements of queue q2 and 
            // adding level below it to queue q1
            while (q2.Count > 0) {
                Node curr = q2.Dequeue();
                currentLevel.Add(curr.data);
                
                if (curr.left != null)
                    q1.Enqueue(curr.left);

                if (curr.right != null)
                    q1.Enqueue(curr.right);
            }
            
            // Storing current level into result 
            if (currentLevel.Count > 0)
                result.Add(currentLevel);
        }

        return result;
    }

    static void Main(string[] args) {
      
         // Binary tree structure:
        //
        //        1
        //       / \
        //      2   3
        //     / \   \
        //    4   5   6
      
        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);
        root.right.right = new Node(6);
      
        List<List<int>> traversal = LevelOrder(root);
      
        foreach (var level in traversal) {
            foreach (int val in level) {
                Console.Write(val + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// JavaScript Program to Print level 
// Order traversal of Binary Tree

class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Returns level order traversal as a 2D array.
function levelOrder(root) {
    const result = [];
    if (root === null) return result;

    const q1 = [];
    const q2 = [];
    
    q1.push(root);

    // Executing loop till both the queues become empty
    while (q1.length > 0 || q2.length > 0) {
        let currentLevel = [];
        
        // Considering elements of queue q1 and 
        // adding level below it to queue q2
        while (q1.length > 0) {
            const curr = q1.shift();
            currentLevel.push(curr.data);

            if (curr.left !== null) {
                q2.push(curr.left);
            }

            if (curr.right !== null) {
                q2.push(curr.right);
            }
        }

        // Storing current level into result
        if (currentLevel.length > 0) {
            result.push(currentLevel);
        }

        currentLevel = [];

        // Considering elements of queue q2 and 
        // adding level below it to queue q1
        while (q2.length > 0) {
            const curr = q2.shift();
            currentLevel.push(curr.data);
            
            if (curr.left !== null) {
                q1.push(curr.left);
            }

            if (curr.right !== null) {
                q1.push(curr.right);
            }
        }
        
        // Storing current level into result 
        if (currentLevel.length > 0) {
            result.push(currentLevel);
        }
    }

    return result;
}

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

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);
root.right.right = new Node(6);

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

Output
1 
2 3 
4 5 6 

Time Complexity: O(n), where n is the number of nodes in Binary Tree.
Auxiliary Space: O(n)

Related articles:


Next Article

Similar Reads