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++ program for printing vertical order // of a given binary tree using 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 order of a // binary tree with given root void printVerticalOrder(Node* root)
{ // Base case
if (!root)
return ;
// Create a map and store vertical order 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 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 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;
} |
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;
// 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;
}
} class Qobj {
int hd;
Node node;
Qobj( int hd, Node node)
{
this .hd = hd;
this .node = node;
}
} public class VerticalOrderTraversal {
// The main function to print vertical order of a
// binary tree with given root
static void printVerticalOrder(Node root)
{
// Base case
if (root == null )
return ;
// Create a map and store vertical order in
// map using function getVerticalOrder()
TreeMap<Integer, ArrayList<Integer> > m = new TreeMap<>();
int hd = 0 ;
// Create queue to do level order traversal.
// Every item of queue contains node and
// horizontal distance.
Queue<Qobj> que = new LinkedList<Qobj>();
que.add( new Qobj( 0 , root));
while (!que.isEmpty()) {
// pop from queue front
Qobj temp = que.poll();
hd = temp.hd;
Node node = temp.node;
// insert this node's data in array of hash
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));
}
// Traverse the map and print nodes at
// every horizontal distance (hd)
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();
}
}
// Driver program to test above functions
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 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 |
// C# program to implement the // above approach using System;
using System.Collections;
using System.Collections.Generic;
class Node{
public int key;
public Node left, right;
// A utility function to // create a new node 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{
// The main function to print // vertical order of a binary // tree with given root static void printVerticalOrder(Node root)
{ // Base case
if (root == null )
return ;
// Create a map and store vertical
// order in map using function
// getVerticalOrder()
SortedDictionary< int ,
ArrayList> m =
new SortedDictionary< int ,
ArrayList>();
int hd = 0;
// Create queue to do level order
// traversal. Every item of queue
// contains node and horizontal
// distance.
Queue que = new Queue();
que.Enqueue( new Qobj(0, root));
while (que.Count != 0)
{
// pop from queue front
Qobj temp = (Qobj)que.Dequeue();
hd = temp.hd;
Node node = temp.node;
// insert this node's data in
// array of hash
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));
}
// Traverse the map and print
// nodes at every horizontal
// distance (hd)
foreach (KeyValuePair< int ,
ArrayList> entry in m)
{
ArrayList al = (ArrayList)entry.Value;
foreach ( int i in al)
Console.Write(i + " " );
Console.Write( "\n" );
}
} // Driver code 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);
} } // This code is contributed by Rutvik_56 |
<script> // Javascript program to implement the // above approach class Node { constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
} // A utility function to // create a new node 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;
}
} // The main function to print // vertical order of a binary // tree with given root function printVerticalOrder(root)
{ // Base case
if (root == null )
return ;
// Create a map and store vertical
// order in map using function
// getVerticalOrder()
var m = new Map();
var hd = 0;
// Create queue to do level order
// traversal. Every item of queue
// contains node and horizontal
// distance.
var que = [];
que.push( new Qobj(0, root));
while (que.length != 0)
{
// pop from queue front
var temp = que[0];
que.shift();
hd = temp.hd;
var node = temp.node;
// insert this node's data in
// array of hash
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));
}
// Traverse the map and print
// nodes at every horizontal
// distance (hd)
[...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>" );
});
} // Driver code 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); // This code is contributed by famously. </script> |
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