Print a Binary Tree in Vertical Order | Set 2 (Map based Method) - GeeksforGeeks

08 Feb, 2022
Given a binary tree, print it vertically. The following example illustrates the 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 a O(n2) solution in the previous post. In this post, an efficient solution based on the hash map is discussed. We need to check the Horizontal Distances from the root for all nodes. If two nodes have the same Horizontal Distance (HD), then they are on the same vertical line. The idea of HD is simple. HD for root is 0, a right edge (edge connecting to right subtree) is considered as +1 horizontal distance and a left edge is considered as -1 horizontal distance. For example, in the above tree, HD for Node 4 is at -2, HD for Node 2 is -1, HD for 5 and 6 is 0 and HD for node 7 is +2. We can do preorder traversal of the given Binary Tree. While traversing the tree, we can recursively calculate HDs. We initially pass the horizontal distance as 0 for root. For left subtree, we pass the Horizontal Distance as Horizontal distance of root minus 1. For right subtree, we pass the Horizontal Distance as Horizontal Distance of root plus 1. For every HD value, we maintain a list of nodes in a hash map. Whenever we see a node in traversal, we go to the hash map entry and add the node to the hash map using HD as a key in a map.Following is the C++ implementation of the above method. Thanks to Chirag for providing the below C++ implementation.
C++
Java
Python3
C#
// C++ program for printing vertical order of a given binary tree#include <iostream>#include <vector>#include <map>using namespace std; // Structure for a binary tree nodestruct Node{    int key;    Node *left, *right;}; // A utility function to create a new nodestruct Node* newNode(int key){    struct Node* node = new Node;    node->key = key;    node->left = node->right = NULL;    return node;} // Utility function to store vertical order in map 'm'// 'hd' is horizontal distance of current node from root.// 'hd' is initially passed as 0void getVerticalOrder(Node* root, int hd, map<int, vector<int>> &m){    // Base case    if (root == NULL)        return;     // Store current node in map 'm'    m[hd].push_back(root->key);     // Store nodes in left subtree    getVerticalOrder(root->left, hd-1, m);     // Store nodes in right subtree    getVerticalOrder(root->right, hd+1, m);} // The main function to print vertical order of a binary tree// with the given rootvoid printVerticalOrder(Node* root){    // Create a map and store vertical order in map using    // function getVerticalOrder()    map < int,vector<int> > m;    int hd = 0;    getVerticalOrder(root, hd,m);     // Traverse the map and print nodes at every horizontal    // 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 functionsint 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);    cout << "Vertical order traversal is n";    printVerticalOrder(root);    return 0;}
// Java program for printing vertical order of a given binary treeimport java.util.TreeMap;import java.util.Vector;import java.util.Map.Entry; public class VerticalOrderBtree{    // Tree node    static class Node    {        int key;        Node left;        Node right;                 // Constructor        Node(int data)        {            key = data;            left = null;            right = null;        }    }         // Utility function to store vertical order in map 'm'    // 'hd' is horizontal distance of current node from root.    // 'hd' is initially passed as 0    static void getVerticalOrder(Node root, int hd,                                TreeMap<Integer,Vector<Integer>> m)    {        // Base case        if(root == null)            return;                 //get the vector list at 'hd'        Vector<Integer> get =  m.get(hd);                 // Store current node in map 'm'        if(get == null)        {            get = new Vector<>();            get.add(root.key);        }        else            get.add(root.key);                 m.put(hd, get);                 // Store nodes in left subtree        getVerticalOrder(root.left, hd-1, m);                 // Store nodes in right subtree        getVerticalOrder(root.right, hd+1, m);    }         // The main function to print vertical order of a binary tree    // with the given root    static void printVerticalOrder(Node root)    {        // Create a map and store vertical order in map using        // function getVerticalOrder()        TreeMap<Integer,Vector<Integer>> m = new TreeMap<>();        int hd =0;        getVerticalOrder(root,hd,m);                 // Traverse the map and print nodes at every horizontal        // distance (hd)        for (Entry<Integer, Vector<Integer>> entry : m.entrySet())        {            System.out.println(entry.getValue());        }    }         // Driver program to test above functions    public static void main(String[] args) {         // TO DO Auto-generated method stub        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.left = new Node(6);        root.right.right = new Node(7);        root.right.left.right = new Node(8);        root.right.right.right = new Node(9);        System.out.println("Vertical Order traversal is");        printVerticalOrder(root);    }}// This code is contributed by Sumit Ghosh
# Python program for printing vertical order of a given# binary tree # A binary tree nodeclass Node:    # Constructor to create a new node    def __init__(self, key):        self.key = key        self.left = None        self.right = None # Utility function to store vertical order in map 'm'# 'hd' is horizontal distance of current node from root# 'hd' is initially passed as 0def getVerticalOrder(root, hd, m):     # Base Case    if root is None:        return         # Store current node in map 'm'    try:        m[hd].append(root.key)    except:        m[hd] = [root.key]         # Store nodes in left subtree    getVerticalOrder(root.left, hd-1, m)         # Store nodes in right subtree    getVerticalOrder(root.right, hd+1, m) # The main function to print vertical order of a binary#tree ith given rootdef printVerticalOrder(root):         # Create a map and store vertical order in map using    # function getVerticalORder()    m = dict()    hd = 0    getVerticalOrder(root, hd, m)         # Traverse the map and print nodes at every horizontal    # distance (hd)    for index, value in enumerate(sorted(m)):        for i in m[value]:            print (i,end=" ")        print()  # Driver program to test above functionroot = 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.right = Node(9)print ("Vertical order traversal is")printVerticalOrder(root) # This code is contributed by Nikhil Kumar Singh(nickzuck_007)
// C# program for printing vertical order of a given binary treeusing System;using System.Collections.Generic; public class VerticalOrderBtree{   // Tree node  public class Node {    public int key;    public Node left;    public Node right;     // Constructor    public Node(int data) {      key = data;      left = null;      right = null;    }  }   // Utility function to store vertical order in map 'm'  // 'hd' is horizontal distance of current node from root.  // 'hd' is initially passed as 0  static void getVerticalOrder(Node root, int hd,                               SortedDictionary<int,                               List<int>> m)  {    // Base case    if (root == null)      return;     // get the vector list at 'hd'    List<int> get = new List<int>();//m[hd];    if(m.ContainsKey(hd))      get.AddRange(m[hd]);         // Store current node in map 'm'    if (get == null) {      get = new List<int>();      get.Add(root.key);    } else      get.Add(root.key);     m[hd] = get;     // Store nodes in left subtree    getVerticalOrder(root.left, hd - 1, m);     // Store nodes in right subtree    getVerticalOrder(root.right, hd + 1, m);  }   // The main function to print vertical order of a binary tree  // with the given root  static void printVerticalOrder(Node root)  {         // Create a map and store vertical order in map using    // function getVerticalOrder()    SortedDictionary<int, List<int>> m = new SortedDictionary<int, List<int>>();    int hd = 0;    getVerticalOrder(root, hd, m);     // Traverse the map and print nodes at every horizontal    // distance (hd)    foreach(KeyValuePair<int, List<int>> entry in m)    {      foreach(int v in entry.Value)        Console.Write(v+" ");      Console.WriteLine();    }  }   // Driver program to test above functions  public static void Main(String[] args) {     // TO DO Auto-generated method stub    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.left = new Node(6);    root.right.right = new Node(7);    root.right.left.right = new Node(8);    root.right.right.right = new Node(9);    Console.WriteLine("Vertical Order traversal is");    printVerticalOrder(root);  }} // This code is contributed by Rajput-Ji
Vertical order traversal is n4 
2 
1 5 6 
3 8 
7 
9 
Time Complexity of hashing based solution can be considered as O(n) under the assumption that we have good hashing function that allows insertion and retrieval operations in O(1) time. In the above C++ implementation, map of STL is used. map in STL is typically implemented using a Self-Balancing Binary Search Tree where all operations take O(Logn) time. Therefore time complexity of the above implementation is O(nLogn).Note that the above solution may not print nodes in same vertical order as they appear in tree. For example, the above program prints 12 before 9. See this for a sample run. 
             1
          /    \ 
         2       3
        /      /  \
       4    5  6    7
                  /  \
                 8 10  9 
                     \
                     11
                       \
                        12
Refer below post for level order traversal based solution. The below post makes sure that nodes of a vertical line are printed in the same order as they appear in the tree.Print a Binary Tree in Vertical Order | Set 3 (Using Level Order Traversal)
Using Preorder Traversal Approach, Maintain the Order of Nodes in Same Vertical Order as They Appear in Tree: 
We can also maintain the order of nodes in same vertical order as they appear in the tree. Nodes having same horizontal distance will print according to level order.  
For example, In below diagram 9 and 12 have same horizontal distance. We can make sure that  if a node like 12 comes below in same vertical line, it is printed after a node like 9
Idea: Instead of using horizontal distance as a key in the map, we will use  horizontal distance + vertical distance as key. We know that the number of nodes can’t be more than integer range in a binary tree.
We will use first 30 bits of key for horizontal distance [MSB to LSB] and will use 30 next bits for vertical distance. Thus keys will be stored in map as per our requirement.
Below is the implementation of above approach.
C++14
// C++ program for printing// vertical order of a given binary// tree#include <bits/stdc++.h>using namespace std; struct Node {    int data;    Node *left, *right;}; struct Node* newNode(int data){    struct Node* node = new Node;    node->data = data;    node->left = node->right = NULL;    return node;} // Store vertical order// in map "m", hd = horizontal// distance, vd = vertical distancevoid preOrderTraversal(Node* root,                       long long int hd,                       long long int vd,                       map<long long int,                       vector<int> >& m){    if (!root)        return;    // key = horizontal    // distance (30 bits) + vertical    // distance (30 bits) map    // will store key in sorted    // order. Thus nodes having same    // horizontal distance    // will sort according to    // vertical distance.    long long val = hd << 30 | vd;     // insert in map    m[val].push_back(root->data);     preOrderTraversal(root->left, hd - 1, vd + 1, m);    preOrderTraversal(root->right, hd + 1, vd + 1, m);} void verticalOrder(Node* root){    // map to store all nodes in vertical order.    // keys will be horizontal + vertical distance.    map<long long int, vector<int> > mp;     preOrderTraversal(root, 0, 1, mp);     // print map    int prekey = INT_MAX;    map<long long int, vector<int> >::iterator it;    for (it = mp.begin(); it != mp.end(); it++) {        if (prekey != INT_MAX            && (it->first >> 30) != prekey) {            cout << endl;        }        prekey = it->first >> 30;        for (int j = 0; j < it->second.size(); j++)            cout << it->second[j] << " ";    }} // Driver codeint 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);    cout << "Vertical order traversal :- " << endl;    verticalOrder(root);    return 0;}
Vertical order traversal :- 
4 
2 
1 5 6 
3 8 
7 
9 
Time Complexity of the above implementation is O(n Log n). 
Auxiliary Space: O(n)
Another Approach using computeIfAbsent method:
We can write the code in a more concise way, by using computeIfAbsent method of the map in java and by using a treemap for natural sorting based upon keys.
Below is the implementation of above approach.
Java
// Java Program for above approachimport java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.TreeMap; class Node {    int data;    Node left, right;     Node(int item)    {        data = item;        left = right = null;    }} public class BinaryTree {     Node root;     // Values class    class Values {        int max, min;    }     // Program to find vertical Order    public void verticalOrder(Node node)    {        Values val = new Values();         // Create TreeMap        Map<Integer, List<Integer> > map            = new TreeMap<Integer, List<Integer> >();         // Function Call to findHorizontalDistance        findHorizontalDistance(node, val, val, 0, map);         // Iterate over map.values()        for (List<Integer> list : map.values()) {            System.out.println(list);        }         // Print "done"        System.out.println("done");    }     // Program to find Horizontal Distance    public void findHorizontalDistance(        Node node, Values min, Values max, int hd,        Map<Integer, List<Integer> > map)    {         // If node is null        if (node == null)            return;         // if hd is less than min.min        if (hd < min.min)            min.min = hd;         // if hd is greater than min.min        if (hd > max.max)            max.max = hd;         // Using computeIfAbsent        map.computeIfAbsent(hd,                            k -> new ArrayList<Integer>())            .add(node.data);         // Function Call with hd equal to hd - 1        findHorizontalDistance(node.left, min, max, hd - 1,                                map);         // Function Call with hd equal to hd + 1        findHorizontalDistance(node.right, min, max,                                hd + 1, map);    }     // Driver Code    public static void main(String[] args)    {         BinaryTree tree = new BinaryTree();         /* Let us construct the tree shown                             in above diagram */        tree.root = new Node(1);        tree.root.left = new Node(2);        tree.root.right = new Node(3);        tree.root.left.left = new Node(4);        tree.root.left.right = new Node(5);        tree.root.right.left = new Node(6);        tree.root.right.right = new Node(7);        tree.root.right.left.right = new Node(8);        tree.root.right.right.right = new Node(9);         System.out.println("vertical order traversal is :");         // Function Call        tree.verticalOrder(tree.root);    }}
vertical order traversal is :
[4]
[2]
[1, 5, 6]
[3, 8]
[7]
[9]
done
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Another Approach using Unordered Map method:
we have seen ordered map above but, its complexity is O(n logn), and also it does not print the vertical nodes of same horizontal distance in correct order.
here we implement this using an unordered map, as unordered map is implemented using a hash table its complexity is O(n), better then using ordered map which is implemented using a BST.
here for printing all nodes of of same horizontal distance from root we use mn and mx two variables which store the minimum and maximum horizontal distance from root.
C++
// C++ program for printing vertical// order of a given binary tree using BFS#include <bits/stdc++.h> using namespace std; // Structure for a binary tree nodestruct Node {    int key;    Node *left, *right;}; // A function to create a new nodeNode* newNode(int key){    Node* node = new Node;    node->key = key;    node->left = node->right = NULL;    return node;} // The main function to print vertical// order of a binary tree with given rootvoid printVerticalOrder(Node* root){    // Base case    if (!root) return;     // Create a map and store vertical    // order in map using      // function getVerticalOrder()    unordered_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> > q;    q.push({root, hd});       // mn and mx contain the minimum and      // maximum horizontal distance from root    int mn=0,mx=0;    while (q.size()>0) {               // pop from queue front        pair<Node*, int> temp = q.front();        q.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)            q.push({node->left, hd - 1});        if (node->right)            q.push({node->right, hd + 1});               // Update mn and mx        if(mn>hd)          mn=hd;        else if(mx<hd)          mx=hd;    }     // run the loop from minimum to maximum    // every horizontal distance hd    for (int i=mn;i<=mx;i++)    {        vector<int> tmp=m[i];        for(int j=0;j<tmp.size();j++)          cout<<tmp[j]<<" ";        cout<<endl;      }} // Driver program to test above functionsint 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;}
Vertical order traversal is 
4 
2 
1 5 6 
3 8 10 
7 11 
9 12 
Time complexity: O(n)
space complexity: O(n)
Here all the nodes of same horizontal distance will be printed in correct order i.e from top to bottom.
csk111165
Akanksha_Rai
nidhi_biet
pkm.softpro
mitravikku
draco_malf0y
iampradeephr
azharhussain161999
anikaseth98
adnanirshad158
amartyaghoshgfg
sagar0719kumar
Rajput-Ji
Accolite
Amazon
BrowserStack
Dell
Flipkart
Grofers
MakeMyTrip
Hash
Tree
Flipkart
Accolite
Amazon
MakeMyTrip
BrowserStack
Dell
Grofers
Hash
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Internal Working of HashMap in Java
Count pairs with given sum
Sort string of characters
Counting frequencies of array elements
Most frequent element in an array
AVL Tree | Set 1 (Insertion)
Level Order Binary Tree Traversal
Write a Program to Find the Maximum Depth or Height of a Tree
Decision Tree
A program to check if a binary tree is BST or not