Print Nodes in Top View of Binary Tree

Top view of a binary tree is the set of nodes visible when the tree is viewed from the top. Given a binary tree, print the top view of it. The output nodes can be printed in any order. Expected time complexity is O(n)

A node x is there in output if x is the topmost node at its horizontal distance. Horizontal distance of left child of a node x is equal to horizontal distance of x minus 1, and that of right child is horizontal distance of x plus 1.

       1
    /     \
   2       3
  /  \    / \
 4    5  6   7
Top view of the above binary tree is
4 2 1 3 7

        1
      /   \
    2       3
      \   
        4  
          \
            5
             \
               6
Top view of the above binary tree is
2 1 3 6

The idea is to do something similar to vertical Order Traversal. Like vertical Order Traversal, we need to put nodes of same horizontal distance together. We do a level order traversal so that the topmost node at a horizontal node is visited before any other node of same horizontal distance below it. Hashing is used to check if a node at given horizontal distance is seen or not.



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to print top
// view of binary tree
  
#include <iostream> 
#include<queue> 
#include<map>
using namespace std;
  
// Structure of binary tree
struct Node
{
    Node * left;
    Node* right;
    int hd;
    int data;
};
  
// function to create a new node
Node* newNode(int key)
{
    Node* node=new Node();
    node->left = node->right = NULL;
    node->data=key;
    return node;
}
  
// function should print the topView of
// the binary tree
void topview(Node* root)
{
    if(root==NULL)
       return;
     queue<Node*>q;
     map<int,int> m; 
     int hd=0;
     root->hd=hd;
       
     // push node and horizontal distance to queue
    q.push(root);
      
    cout<< "The top view of the tree is : \n";
      
    while(q.size())
    {
        hd=root->hd;
          
        // count function returns 1 if the container 
        // contains an element whose key is equivalent 
        // to hd, or returns zero otherwise.
        if(m.count(hd)==0)  
        m[hd]=root->data;
        if(root->left)
        {
            root->left->hd=hd-1;
            q.push(root->left);
        }
        if(root->right)
        {
            root->right->hd=hd+1;
            q.push(root->right);
        }
        q.pop();
        root=q.front();
        
    }
      
      
      
     for(auto i=m.begin();i!=m.end();i++)
    {
        cout<<i->second<<" ";
    }
      
}
   
// Driver Program to test above functions
int main()
{
    /* Create following Binary Tree 
            
        / \ 
        2 3 
        
            
            
            
            
                6*/
   Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->right = newNode(4);
    root->left->right->right = newNode(5);
    root->left->right->right->right = newNode(6);
    cout<<"Following are nodes in top view of Binary Tree\n"
    topview(root);
    return 0;
}
/* This code is contributed by Niteesh Kumar */

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to print top
// view of binary tree
import java.util.Queue;
import java.util.TreeMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
  
// class to create a node
class Node {
    int data;
    Node left, right;
  
    public Node(int data) {
        this.data = data;
        left = right = null;
    }
}
  
// class of binary tree
class BinaryTree {
    Node root;
  
    public BinaryTree() {
        root = null;
    }
      
    // function should print the topView of
    // the binary tree
    private void TopView(Node root) {
        class QueueObj {
            Node node;
            int hd;
  
            QueueObj(Node node, int hd) {
                this.node = node;
                this.hd = hd;
            }
        }
        Queue<QueueObj> q = new LinkedList<QueueObj>();
        Map<Integer, Node> topViewMap = new TreeMap<Integer, Node>();
  
        if (root == null) {
            return;
        } else {
            q.add(new QueueObj(root, 0));
        }
  
        System.out.println("The top view of the tree is : ");
          
        // count function returns 1 if the container 
        // contains an element whose key is equivalent 
        // to hd, or returns zero otherwise.
        while (!q.isEmpty()) {
            QueueObj tmpNode = q.poll();
            if (!topViewMap.containsKey(tmpNode.hd)) {
                topViewMap.put(tmpNode.hd, tmpNode.node);
            }
  
            if (tmpNode.node.left != null) {
                q.add(new QueueObj(tmpNode.node.left, tmpNode.hd - 1));
            }
            if (tmpNode.node.right != null) {
                q.add(new QueueObj(tmpNode.node.right, tmpNode.hd + 1));
            }
  
        }
        for (Entry<Integer, Node> entry : topViewMap.entrySet()) {
            System.out.print(entry.getValue().data);
        }
    }
      
    // Driver Program to test above functions
    public static void main(String[] args) 
    
        /* Create following Binary Tree 
            
        / \ 
        2 3 
        
            
            
            
            
                6*/
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.right = new Node(4);
        tree.root.left.right.right = new Node(5);
        tree.root.left.right.right.right = new Node(6);
        System.out.println("Following are nodes in top view of Binary Tree"); 
        tree.TopView(tree.root); 
    
      
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to print top 
# view of binary tree
  
# Binary Tree Node 
""" utility that allocates a newNode 
with the given key """
class newNode: 
  
    # Construct to create a newNode 
    def __init__(self, key): 
        self.data = key
        self.left = None
        self.right = None
        self.hd = 0
  
# function should print the topView 
# of the binary tree 
def topview(root) :
  
    if(root == None) :
        return
    q = []
    m = dict()
    hd = 0
    root.hd = hd 
  
    # push node and horizontal
    # distance to queue 
    q.append(root) 
  
    while(len(q)) :
        root = q[0]
        hd = root.hd 
          
        # count function returns 1 if the 
        # container contains an element 
        # whose key is equivalent to hd, 
        # or returns zero otherwise. 
        if hd not in m:
            m[hd] = root.data 
        if(root.left) :         
            root.left.hd = hd - 1
            q.append(root.left) 
          
        if(root.right):         
            root.right.hd = hd + 1
            q.append(root.right) 
          
        q.pop(0)
    for i in sorted (m):
        print(m[i], end = "") 
  
# Driver Code 
if __name__ == '__main__':
  
    """ Create following Binary Tree 
            
        / \ 
        2 3 
        
            
            
            
            
                6*"""
    root = newNode(1
    root.left = newNode(2
    root.right = newNode(3
    root.left.right = newNode(4
    root.left.right.right = newNode(5
    root.left.right.right.right = newNode(6
    print("Following are nodes in top"
          "view of Binary Tree"
    topview(root)
  
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

chevron_right



Output:

Following are nodes in top view of Binary Tree
2136

Another approach:

This approach does not require a queue. Here we use the two variables, one for vertical distance of current node from the root and another for the depth of the current node from the root. We use the vertical distance for indexing. If one node with the same vertical distance comes again, we check if depth of new node is lower or higher with respect to the current node with same vertical distance in the map. If depth of new node is lower, then we replace it.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<bits/stdc++.h>
using namespace std;
  
// Structure of binary tree
struct Node{
    Node * left;
    Node* right;
    int data;
};
  
// function to create a new node
Node* newNode(int key){
    Node* node=new Node();
    node->left = node->right = NULL;
    node->data=key;
    return node;
}
  
// function to fill the map
void fillMap(Node* root,int d,int l,map<int,pair<int,int>> &m){
    if(root==NULL) return;
  
    if(m.count(d)==0){
        m[d] = make_pair(root->data,l);
    }else if(m[d].second>l){
        m[d] = make_pair(root->data,l);
    }
  
    fillMap(root->left,d-1,l+1,m);
    fillMap(root->right,d+1,l+1,m);
}
  
// function should print the topView of
// the binary tree
void topView(struct Node *root){
  
    //map to store the pair of node value and its level 
    //with respect to the vertical distance from root. 
    map<int,pair<int,int>> m;
  
    //fillmap(root,vectical_distance_from_root,level_of_node,map)
    fillMap(root,0,0,m);
  
    for(auto it=m.begin();it!=m.end();it++){
        cout << it->second.first << " ";
    }
}
// Driver Program to test above functions
int main(){
    Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->right = newNode(4);
    root->left->right->right = newNode(5);
    root->left->right->right->right = newNode(6);
    cout<<"Following are nodes in top view of Binary Tree\n"
    topView(root);
    return 0;
}
/* This code is contributed by Akash Debnath */

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Binary Tree Node 
""" utility that allocates a newNode 
with the given key """
class newNode: 
  
    # Construct to create a newNode 
    def __init__(self, key): 
        self.data = key 
        self.left = None
        self.right = None
  
# function to fill the map
def fillMap(root, d, l, m):
    if(root == None):
        return
      
    if d not in m:
        m[d] = [root.data,l]
    elif(m[d][1] > l):
        m[d] = [root.data,l]
    fillMap(root.left, d - 1, l + 1, m)
    fillMap(root.right, d + 1, l + 1, m)
  
# function should prthe topView of
# the binary tree
def topView(root):
      
    # map to store the pair of node value and its level 
    # with respect to the vertical distance from root. 
    m = {}
      
    fillMap(root, 0, 0, m)
    for it in sorted (m.keys()):
        print(m[it][0], end = " ")
      
# Driver Code
root = newNode(1)
root.left = newNode(2)
root.right = newNode(3)
root.left.right = newNode(4)
root.left.right.right = newNode(5)
root.left.right.right.right = newNode(6)
print("Following are nodes in top view of Binary Tree")
topView(root)
  
# This code is contributed by SHUBHAMSINGH10

chevron_right



Output:

Following are nodes in top view of Binary Tree
2 1 3 6

This approach is contributed by Akash Debnath

Time Complexity of the above implementation is O(n) where n is the number of nodes in the given binary tree. The assumption here is that add() and contains() methods of HashSet work in O(1) time.

This article is contributed by Rohan. 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