Open In App

Level order traversal of Binary Tree using Morris Traversal

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary tree, the task is to traverse the Binary Tree in level order fashion.
Examples: 
 

Input: 
         1
        / \
       2   3
Output:
1
2 3

Input:
         5
        / \
       2   3
        \
         6
Output:
5
2 3
6

 

Approach: The idea is to use Morris Preorder Traversal to traverse the tree in level order traversal.
Observations: There are mainly two observations for the traversal of the tree using Morris preorder traversal. That is – 
 

  • In Preorder traversal the left-most nodes of a level are visited first due which it can be used to traverse the tree in level order fashion.
  • As we maintain the horizontal distance of the nodes in the top view of the binary tree, Similarly If we maintain the level of the current node and increment or decrement the level accordingly as per the movement, Then the nodes can be traversed easily.

As in the Morris preorder traversal, we connect the right-most node of the left child to its inorder successor to maintain the movement such that we can traverse back to the right child of the parent node after completely exploring the left child of the parent. Therefore, while moving to the rightmost child of the left child we can keep track of the number of the increment in the level to compute the level inorder successor of the child. 
Below is the explanation of the approach with the help of example: 
 

Below is the implementation of the above approach:
 

C++




// C++ implementation of the level
// order traversal using Morris traversal
#include<bits/stdc++.h>
using namespace std;
 
// structure of the node of the binary tree
struct Node{
    int data;
    Node* left;
    Node* right;
    Node(int data){
        this->data = data;
        this->right = NULL;
        this->left = NULL;
    }
};
 
vector<pair<Node*, int>> traversal;
 
// function to traverse the binary
// tree in the level order fashion
void levelOrderTraversal(Node* root)
{
   
    // current node is marked as the root node
    Node* curr = root;
    int level = 0;
     
    // loop to traverse the binary tree until the current node
    // is not null
    while(curr != NULL)
    {
       
        // if left child is null, print the
        // current node data and update the
        // current pointer to right child.
        if(curr->left == NULL)
        {
           
            // return the current node with
            // its level
            traversal.push_back({curr, level});
            curr = curr->right;
            if(curr != NULL){
                level += 1;
            }else{
                level -= 1;
            }
        }
        else{
            // find the inorder predecessor
            Node* prev = curr->left;
            int toUp = 0;
             
            // loop to find the right most
            // node of the left child of the current node
            while(prev->right != NULL && prev->right != curr){
                prev = prev->right;
                toUp += 1;
            }
             
            // If the right child of inorder
           // predecessor already points to
           // the current node, update the
           // current with it's right child
           if(prev->right == curr){
               prev->right = NULL;
               curr = curr->right;
               level -= toUp + 1;
           }
           
           // else If right child doesn't
           // point to the current node,
           // then print this node's data
           // and update the right child
           // pointer with the current node
           // and update the current with
           // it's left child
           else {
               traversal.push_back({curr, level});
               prev->right = curr;
               curr = curr->left;
               level += 1;
           }
        }
    }
}
 
int main()
{
   
    // create a binary tree
    Node* root = new Node(5);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->right = new Node(6);
     
    // traverse the tree in level order traversal
    levelOrderTraversal(root);
     
    // find the height of the tree
    int h = 0;
    for(auto i : traversal){
        h = max(h, i.second+1);
    }
     
    // print the date of nodes at each level
    for(int i = 0; i<h; i++){
        for(auto j : traversal){
            if(j.second == i){
                cout<<j.first->data<<" ";
            }
        }
        cout<<endl;
    }
    return 0;
}
 
// This code is contributed by Yash Agarwal(yashagarwal2852002)


Python3




# Python implementation of the Level
# order traversal using Morris traversal
 
# Class of the node of the
# Binary Tree
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Function to traverse the Binary
# tree in the Level Order Fashion
def levelOrderTraversal(root):
     
    # Current Node is marked as
    # the Root Node
    curr = root
    level = 0
 
    # Loop to traverse the Binary
    # Tree until the current node
    # is not Null
    while curr:
 
        # If left child is null, print the
        # current node data. And, update 
        # the current pointer to right child.
        if curr.left is None:
 
            # Return the current node with
            # its level
            yield [curr, level]
            curr = curr.right
            if curr:
                level += 1
            else:
                level -= 1
        else:
 
            # Find the inorder predecessor
            prev = curr.left
            to_up = 0
 
            # Loop to find the right most
            # node of the left child of the
            # current node
            while prev.right is not None and \
                    prev.right is not curr:
                prev = prev.right
                to_up += 1
 
            # If the right child of inorder
            # predecessor already points to
            # the current node, update the 
            # current with it's right child
            if prev.right is curr:
                prev.right = None
                curr = curr.right
                level -= to_up + 1
             
            # else If right child doesn't
            # point to the current node,
            # then print this node's data
            # and update the right child
            # pointer with the current node 
            # and update the current with
            # it's left child
            else:
                yield [curr, level]
                prev.right = curr 
                curr = curr.left
                level += 1
 
# Driver Code
if __name__ == "__main__":
    root = Node(5)
    root.left = Node(2)
    root.right = Node(3)
    root.left.right = Node(6)
 
    # Output List to store the
    # Level Order Traversed Nodes
    outputData = [[] for i in range(100)]
 
    for node, level in levelOrderTraversal(root):
        outputData[level].append(node.data)
 
    h = 0
 
    # Loop to find the height of the
    # Binary Tree
    for i in outputData:
        if i:
            h += 1
        else:
            break
 
    # Loop to print the Data
    for i in range(h):
        print(' '.join(map(str, outputData[i])))


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// class to represent tree node
public class Node{
    public int data;
    public Node left, right;
    public Node(int item){
        data = item;
        left = null;
        right = null;
    }
}
 
// class to print desired output
public class BinaryTree{
    Node root;
    List<Tuple<Node, int>> traversal = new List<Tuple<Node, int>>();
     
    void levelOrderTraversal(){
        // current node is marked as the root node
        Node curr = root;
        int level = 0;
         
        // loop to traverse the binary tree until the current node
        while(curr != null){
            // if left child is null, print the
            // current node data and update the
            // current pointer to right child.
            if(curr.left == null){
                // return the current node with
                // its level
                traversal.Add(new Tuple<Node, int>(curr, level));
                curr = curr.right;
                if(curr != null){
                    level += 1;
                }else{
                    level -= 1;
                }
            }
            else{
                // find the inorder predecessor
                Node prev = curr.left;
                int toUp = 0;
                  
                // loop to find the right most
                // node of the left child of the current node
                while(prev.right != null && prev.right != curr){
                    prev = prev.right;
                    toUp += 1;
                }
                  
               // If the right child of inorder
               // predecessor already points to
               // the current node, update the
               // current with it's right child
               if(prev.right == curr){
                   prev.right = null;
                   curr = curr.right;
                   level -= toUp + 1;
               }
                
               // else If right child doesn't
               // point to the current node,
               // then print this node's data
               // and update the right child
               // pointer with the current node
               // and update the current with
               // it's left child
               else {
                   traversal.Add(new Tuple<Node, int>(curr, level));
                   prev.right = curr;
                   curr = curr.left;
                   level += 1;
               }
            }
        }
    }
     
    public static void Main(){
        /* creating a binary tree and entering
        the nodes */
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.right = new Node(6);
     
        // traverse the tree in level order traversal
        tree.levelOrderTraversal();
         
        // find the height of the tree
        int h = 0;
        foreach(var i in tree.traversal){
            h = Math.Max(h, i.Item2 + 1);
        }
        // print the date of nodes at each level
        for(int i = 0; i<h; i++){
            foreach(var j in tree.traversal){
                if(j.Item2 == i){
                    Console.Write(j.Item1.data + " ");
                }
            }
            Console.WriteLine(" ");
        }
    }
}
// THIS CODE IS CONTRIBUTED BY KIRIT AGARWAL(KIRITAGARWAL23121999)


Javascript




       // JavaScript code for the above approach
       class Node {
           constructor(data) {
               this.data = data;
               this.left = null;
               this.right = null;
           }
       }
 
       // Function to traverse the Binary
       // tree in the Level Order Fashion
       function* levelOrderTraversal(root)
       {
        
           // Current Node is marked as
           // the Root Node
           let curr = root;
           let level = 0;
 
           // Loop to traverse the Binary
           // Tree until the current node
           // is not Null
           while (curr) {
               // If left child is null, print the
               // current node data. And, update 
               // the current pointer to right child.
               if (!curr.left) {
                   // Return the current node with
                   // its level
                   yield [curr, level];
                   curr = curr.right;
                   if (curr) {
                       level += 1;
                   } else {
                       level -= 1;
                   }
               } else {
                   // Find the inorder predecessor
                   let prev = curr.left;
                   let toUp = 0;
 
                   // Loop to find the right most
                   // node of the left child of the
                   // current node
                   while (prev.right && prev.right !== curr) {
                       prev = prev.right;
                       toUp += 1;
                   }
 
                   // If the right child of inorder
                   // predecessor already points to
                   // the current node, update the 
                   // current with it's right child
                   if (prev.right === curr) {
                       prev.right = null;
                       curr = curr.right;
                       level -= toUp + 1;
                   }
                   // else If right child doesn't
                   // point to the current node,
                   // then print this node's data
                   // and update the right child
                   // pointer with the current node 
                   // and update the current with
                   // it's left child
                   else {
                       yield [curr, level];
                       prev.right = curr;
                       curr = curr.left;
                       level += 1;
                   }
               }
           }
       }
 
       // Create a binary tree
       const root = new Node(5);
       root.left = new Node(2);
       root.right = new Node(3);
       root.left.right = new Node(6);
 
       // Traverse the tree in level order
       const traversal = [...levelOrderTraversal(root)];
 
       // Find the height of the tree
       let h = 0;
       for (const [node, level] of traversal) {
           h = Math.max(h, level + 1);
       }
 
       // Print the data of the nodes at each level
       for (let i = 0; i < h; i++) {
           for (const [node, level] of traversal) {
               if (level === i) {
                   console.log(node.data+" ");
               }
           }
           console.log("<br>");
       }
 
// This code is contributed by Potta Lokesh.


Java




// JAVA implementation of the level
// order traversal using Morris traversal
import java.util.*;
 
// structure of the node of the binary tree
class Node{
    int data;
    Node left;
    Node right;
    public Node(int data)
    {
        this.data=data;
    }
}
public class Main {
 
static ArrayList<Object[]> traversal;
 
    // function to traverse the binary
    // tree in the level order fashion
    public static void levelOrderTraversal(Node root)
    {
        // current node is marked as the root node
        Node curr=root;
        int level=0;
        // loop to traverse the binary tree until the current node
        // is not null
        while(curr!=null)
        {
            // if left child is null, print the
            // current node data and update the
            // current pointer to right child.
            if(curr.left==null)
            {
                // return the current node with
                // its level
                traversal.add(new Object[]{curr,new Integer(level)});
                curr=curr.right;
                if(curr!=null)
                {
                    level++;
                }else
                    level--;
            }
            else{
                // find the inorder predecessor
                Node prev=curr.left;
                int toUp=0;
 
                // loop to find the right most
                // node of the left child of the current node
                while(prev.right!=null && prev.right!=curr)
                {
                    prev=prev.right;
                    toUp++;
                }
                // If the right child of inorder
                // predecessor already points to
                // the current node, update the
                // current with it's right child
                if(prev.right==curr)
                {
                    prev.right=null;
                    curr=curr.right;
                    level-=toUp+1;
                }
                // else If right child doesn't
                // point to the current node,
                // then print this node's data
                // and update the right child
                // pointer with the current node
                // and update the current with
                // it's left child
                else{
                    traversal.add(new Object[]{curr,new Integer(level)});
                    prev.right=curr;
                    curr=curr.left;
                    level++;
                }
            }
        }
    }
    public static void main(String[] args)
    {
        // create a binary tree
        Node root=new Node(5);
        root.left=new Node(2);
        root.right=new Node(3);
        root.left.right=new Node(6);
        traversal=new ArrayList<>();
 
        // traverse the tree in level order traversal
        levelOrderTraversal(root);
 
        // find the height of the tree
        int h=0;
        for(Object[] i:traversal)
        {
            h=Math.max(h,(int)i[1]+1);
        }
 
        // print the date of nodes at each level
        for(int i = 0; i<h; i++){
            for(Object[] j : traversal){
                if((int)j[1] == i){
 
                    System.out.print(((Node)j[0]).data+" ");
                }
            }
            System.out.println();
        }
    }
}


Output: 

5
2 3
6

 

Performance Analysis: 
 

  • Time Complexity: As in the above approach, every node is touched at max twice due to which the time complexity is O(N), where N is the number of nodes.
  • Auxiliary Space: As in the above approach, there is no extra space used due to which auxiliary space used will be O(1)

 



Last Updated : 17 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads