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 the above approach uses preorder traversal, nodes in a vertical line may not be printed in the same order as they appear in the tree. For example, the above solution prints 12 before 9 in the 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 the same vertical line, it is printed after a node like 9 which comes above in the 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.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
Node *left, *right;
};
Node* newNode( int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return node;
}
void printVerticalOrder(Node* root)
{
if (!root)
return ;
map< int , vector< int > > m;
int hd = 0;
queue<pair<Node*, int > > que;
que.push(make_pair(root, hd));
while (!que.empty()) {
pair<Node*, int > temp = que.front();
que.pop();
hd = temp.second;
Node* node = temp.first;
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));
}
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;
}
}
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;
}
|
Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;
class Node {
int key;
Node left, right;
Node newNode( int key)
{
Node node = new Node();
node.key = key;
node.left = node.right = null ;
return node;
}
}
class Qobj {
int hd;
Node node;
Qobj( int hd, Node node)
{
this .hd = hd;
this .node = node;
}
}
public class VerticalOrderTraversal {
static void printVerticalOrder(Node root)
{
if (root == null )
return ;
TreeMap<Integer, ArrayList<Integer> > m = new TreeMap<>();
int hd = 0 ;
Queue<Qobj> que = new LinkedList<Qobj>();
que.add( new Qobj( 0 , root));
while (!que.isEmpty()) {
Qobj temp = que.poll();
hd = temp.hd;
Node node = temp.node;
if (m.containsKey(hd)) {
m.get(hd).add(node.key);
}
else {
ArrayList<Integer> al = new ArrayList<>();
al.add(node.key);
m.put(hd, al);
}
if (node.left != null )
que.add( new Qobj(hd - 1 , node.left));
if (node.right != null )
que.add( new Qobj(hd + 1 , node.right));
}
for (Map.Entry<Integer, ArrayList<Integer> > entry : m.entrySet()) {
ArrayList<Integer> al = entry.getValue();
for (Integer i : al)
System.out.print(i + " " );
System.out.println();
}
}
public static void main(String ar[])
{
Node n = new Node();
Node root;
root = n.newNode( 1 );
root.left = n.newNode( 2 );
root.right = n.newNode( 3 );
root.left.left = n.newNode( 4 );
root.left.right = n.newNode( 5 );
root.right.left = n.newNode( 6 );
root.right.right = n.newNode( 7 );
root.right.left.right = n.newNode( 8 );
root.right.right.right = n.newNode( 9 );
root.right.right.left = n.newNode( 10 );
root.right.right.left.right = n.newNode( 11 );
root.right.right.left.right.right = n.newNode( 12 );
System.out.println( "Vertical order traversal is " );
printVerticalOrder(root);
}
}
|
Python3
import collections
class Node:
def __init__( self , data):
self .data = data
self .left = self .right = None
def verticalTraverse(root):
if root is None :
return
queue = []
m = {}
hd_node = {}
queue.append(root)
hd_node[root] = 0
m[ 0 ] = [root.data]
while len (queue) > 0 :
temp = queue.pop( 0 )
if temp.left:
queue.append(temp.left)
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:
queue.append(temp.right)
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)
sorted_m = collections.OrderedDict( sorted (m.items()))
for i in sorted_m.values():
for j in i:
print (j, " " , end = "")
print ()
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)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class Node{
public int key;
public Node left, right;
public Node newNode( int key)
{
Node node = new Node();
node.key = key;
node.left = node.right =
null ;
return node;
}
}
class Qobj{
public int hd;
public Node node;
public Qobj( int hd,
Node node)
{
this .hd = hd;
this .node = node;
}
}
class VerticalOrderTraversal{
static void printVerticalOrder(Node root)
{
if (root == null )
return ;
SortedDictionary< int ,
ArrayList> m =
new SortedDictionary< int ,
ArrayList>();
int hd = 0;
Queue que = new Queue();
que.Enqueue( new Qobj(0, root));
while (que.Count != 0)
{
Qobj temp = (Qobj)que.Dequeue();
hd = temp.hd;
Node node = temp.node;
if (m.ContainsKey(hd))
{
m[hd].Add(node.key);
}
else
{
ArrayList al = new ArrayList();
al.Add(node.key);
m[hd] = al;
}
if (node.left != null )
que.Enqueue( new Qobj(hd - 1,
node.left));
if (node.right != null )
que.Enqueue( new Qobj(hd + 1,
node.right));
}
foreach (KeyValuePair< int ,
ArrayList> entry in m)
{
ArrayList al = (ArrayList)entry.Value;
foreach ( int i in al)
Console.Write(i + " " );
Console.Write( "\n" );
}
}
public static void Main( string []arr)
{
Node n = new Node();
Node root;
root = n.newNode(1);
root.left = n.newNode(2);
root.right = n.newNode(3);
root.left.left = n.newNode(4);
root.left.right = n.newNode(5);
root.right.left = n.newNode(6);
root.right.right = n.newNode(7);
root.right.left.right = n.newNode(8);
root.right.right.right = n.newNode(9);
root.right.right.left = n.newNode(10);
root.right.right.left.right = n.newNode(11);
root.right.right.left.right.right = n.newNode(12);
Console.Write( "Vertical order traversal is \n" );
printVerticalOrder(root);
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
}
function newNode(key)
{
var node = new Node();
node.key = key;
node.left = node.right =
null ;
return node;
}
class Qobj{
constructor(hd, node)
{
this .hd = hd;
this .node = node;
}
}
function printVerticalOrder(root)
{
if (root == null )
return ;
var m = new Map();
var hd = 0;
var que = [];
que.push( new Qobj(0, root));
while (que.length != 0)
{
var temp = que[0];
que.shift();
hd = temp.hd;
var node = temp.node;
if (m.has(hd))
{
var al = m.get(hd);
al.push(node.key);
m.set(hd, al);
}
else
{
var al = [];
al.push(node.key);
m.set(hd, al);
}
if (node.left != null )
que.push( new Qobj(hd - 1,
node.left));
if (node.right != null )
que.push( new Qobj(hd + 1,
node.right));
}
[...m].sort((a,b)=>a[0]-b[0]).forEach(tmp => {
var al = tmp[1];
for ( var i of al)
document.write(i + " " );
document.write( "<br>" );
});
}
var 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);
document.write( "Vertical order traversal is <br>" );
printVerticalOrder(root);
</script>
|
Output
Vertical order traversal is
4
2
1 5 6
3 8 10
7 11
9 12
Time Complexity of the above implementation is O(n Log n). Note that the above implementation uses a map which is implemented using self-balancing BST.
We can reduce the time complexity to O(n) using unordered_map. To print nodes in the 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)
?list=PLqM7alHXFySGwXaessYMemAnITqlZdZVE
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
12 Sep, 2023
Like Article
Save Article