Print a Binary Tree in Vertical Order | Set 3 (Using Level Order Traversal)

Given a binary tree, print it vertically. The following example illustrates vertical order traversal.

       
           1
         /   \
       2       3
     /  \     /  \
   4     5   6    7
              \    \
               8    9            
              
The output of print this tree vertically will be:
4
2
1 5 6
3 8
7
9



We have discussed an efficient approach in below post.

Print a Binary Tree in Vertical Order | Set 2 (Hashmap based Method)

The above solution uses preorder traversal and Hashmap to store nodes according to horizontal distances. Since above approach uses preorder traversal, nodes in a vertical line may not be prined in same order as they appear in tree. For example, the above solution prints 12 before 9 in below tree. See this for a sample run.

             1
          /     \
         2       3
        /  \    /  \
       4    5  6    7
                \  /  \
                 8 10  9 
                     \
                     11
                       \
                        12      

If we use level order traversal, we can make sure that if a node like 12 comes below in same vertical line, it is printed after a node like 9 which comes above in vertical line.

1. To maintain a hash for the branch of each node.
2. Traverse the tree in level order fashion.
3. In level order traversal, maintain a queue
   which holds, node and its vertical branch.
    * pop from queue.
    * add this node's data in vector corresponding
      to its branch in the hash.
    * if this node hash left child, insert in the 
      queue, left with branch - 1.
    * if this node hash right child, insert in the 
      queue, right with branch + 1.

C++

// C++ program for printing vertical order
// of a given binary tree usin BFS.
#include<bits/stdc++.h>
  
using namespace std;
  
// Structure for a binary tree node
struct Node
{
    int key;
    Node *left, *right;
};
  
// A utility function to create a new node
Node* newNode(int key)
{
    Node* node = new Node;
    node->key = key;
    node->left = node->right = NULL;
    return node;
}
  
// The main function to print vertical oder of a
// binary tree with given root
void printVerticalOrder(Node* root)
{
    // Base case
    if (!root)
        return;
  
    // Create a map and store vertical oder in
    // map using function getVerticalOrder()
    map < int,vector<int> > m;
    int hd = 0;
  
    // Create queue to do level order traversal.
    // Every item of queue contains node and
    // horizontal distance.
    queue<pair<Node*, int> > que;
    que.push(make_pair(root, hd));
  
     while (!que.empty())
     {
        // pop from queue front
        pair<Node *,int> temp = que.front();
        que.pop();
        hd = temp.second;
        Node* node = temp.first;
  
        // insert this node's data in vector of hash
        m[hd].push_back(node->key);
  
        if (node->left != NULL)
            que.push(make_pair(node->left, hd-1));
        if (node->right != NULL)
            que.push(make_pair(node->right, hd+1));
    }
  
    // Traverse the map and print nodes at
    // every horigontal distance (hd)
    map< int,vector<int> > :: iterator it;
    for (it=m.begin(); it!=m.end(); it++)
    {
        for (int i=0; i<it->second.size(); ++i)
            cout << it->second[i] << " ";
        cout << endl;
    }
}
  
// Driver program to test above functions
int main()
{
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->right->left->right = newNode(8);
    root->right->right->right = newNode(9);
    root->right->right->left= newNode(10);
    root->right->right->left->right= newNode(11);
    root->right->right->left->right->right= newNode(12);
    cout << "Vertical order traversal is \n";
    printVerticalOrder(root);
    return 0;
}

Python3

#python3 Program to print zigzag traversal of binary tree
import collections
# Binary tree node
class Node:
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
  
# function to print vertical order traversal of binary tree
def verticalTraverse(root):
  
    # Base case
    if root is None:
        return
  
    # Create empty queue for level order traversal
    queue = []
  
    # create a map to store nodes at a particular
    # horizontal distance
    m = {}
  
    # map to store horizontal distance of nodes
    hd_node = {}
  
    # enqueue root
    queue.append(root)
    # store the horizontal distance of root as 0
    hd_node[root] = 0
  
    m[0] = [root.data]
  
    # loop will run while queue is not empty
    while len(queue) > 0:
  
        # dequeue node from queue
        temp = queue.pop(0)
  
        if temp.left:
            # Enqueue left child
            queue.append(temp.left)
  
            # Store the horizontal distance of left node
            # hd(left child) = hd(parent) -1
            hd_node[temp.left] = hd_node[temp] - 1
            hd = hd_node[temp.left]
  
            if m.get(hd) is None:
                m[hd] = []
  
            m[hd].append(temp.left.data)
  
        if temp.right:
            # Enqueue right child
            queue.append(temp.right)
  
            # store the horizontal distance of right child
            # hd(right child) = hd(parent) + 1
            hd_node[temp.right] = hd_node[temp] + 1
            hd = hd_node[temp.right]
  
            if m.get(hd) is None:
                m[hd] = []
  
            m[hd].append(temp.right.data)
  
    # Sort the map according to horizontal distance
    sorted_m = collections.OrderedDict(sorted(m.items()))
  
    # Traverse the sorted map and print nodes at each horizontal distance
    for i in sorted_m.values():
        for j in i:
            print(j, " ", end="")
        print()
  
# Driver program to check above function
"""
Constructed binary tree is 
            1
        / \
        2     3
    / \ / \
    4     5 6     7
            \ / \
            8 10 9
                \
                11
                    
                    12
                  
"""
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
root.right.left.right =Node(8)
root.right.right.left = Node(10)
root.right.right.right = Node(9)
root.right.right.left.right = Node(11)
root.right.right.left.right.right = Node(12)
print("Vertical order traversal is ")
verticalTraverse(root)
  
# This code is contributed by Shweta Singh


Output:

Vertical order traversal is 
4  
2  
1  5  6  
3  8  10  
7  11  
9  12

Time Complexity of above implementation is O(n Log n). Note that above implementation uses map which is implemented using self-balancing BST.

We can reduce time complexity to O(n) using unordered_map. To print nodes in desired order, we can have 2 variables denoting min and max horizontal distance. We can simply iterate from min to max horizontal distance and get corresponding values from Map. So it is O(n)

Auxiliary Space : O(n)

This article is contributed by Sahil Chhabra (akku). If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : shweta44