Friday, December 27, 2024
Google search engine
HomeData Modelling & AIPrint Nodes in Top View of Binary Tree

Print Nodes in Top View of Binary Tree

The 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. A node x is there in the output if x is the topmost node at its horizontal distance. The horizontal distance of the left child of a node x is equal to a horizontal distance of x minus 1, and that of a right child is the horizontal distance of x plus 1. 

Examples:

Input:     1
           /     \
         2       3
       /  \    / \
     4    5  6   7

Output: Top view of the above binary tree is: 4 2 1 3 7

Input:         1
                 /   \
              2       3
               \   
                4  
                  \
                   5
                    \
                     6

Output: Top view of the above binary tree is: 2 1 3 6

Approach: To solve the problem follow the below idea: 

The idea is to do something similar to vertical Order Traversal. Like vertical Order Traversal, we need to put nodes of the 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 the same horizontal distance below it. Hashing is used to check if a node at a given horizontal distance is seen or not. 

Follow the below steps to solve the problem:

  • Create a function to print the top view of the binary tree
  • If the root is equal to the null value then return from the function (Base case)
  • Create a queue of type Node* and a map of type <int, int> and a variable hd to calculate the horizontal distance
  • Set hd of the root equal to zero and push it into the queue
  • Run a while loop till the queue is not empty
    • set hd equal to root->hd
    • Check if this hd already exists in the map, If not then set this node->val in map[hd]
    • If root->left exists then set its hd = root->hd – 1 and push it into the queue
    • If root->right exists then set its hd = root->hd + 1 and push it into the queue
    • Pop the front element of the queue and set its value in the root
  • Print the answer using the map

Below is the implementation of the above approach:

C++14




// C++ program to print top
// view of binary tree
 
#include <bits/stdc++.h>
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 code
int main()
{
    /* Create following Binary Tree
         1
        / \
       2   3
        \
          4
           \
            5
              \
               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);
    topview(root);
    return 0;
}
/* This code is contributed by Niteesh Kumar */


Java




// Java program to print top
// view of binary tree
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.TreeMap;
 
// 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 (Map.Entry<Integer, Node> entry :
             topViewMap.entrySet()) {
            System.out.print(entry.getValue().data + " ");
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        /* Create following Binary Tree
        1
       / \
      2   3
       \
         4
          \
           5
             \
              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);
        tree.TopView(tree.root);
    }
}


Python3




# 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
         1
        / \
       2   3
        \
          4
           \
            5
              \
               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("The top view of the tree is: ")
    topview(root)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#




// C# program to print top
// view of binary tree
using System;
using System.Collections;
using System.Collections.Generic;
 
// Class to create a node
class Node {
    public int data;
    public Node left, right;
 
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
};
 
class QueueObj {
    public Node node;
    public int hd;
 
    public QueueObj(Node node, int hd)
    {
        this.node = node;
        this.hd = hd;
    }
};
 
// Class of binary tree
class BinaryTree {
 
    Node root;
 
    public BinaryTree() { root = null; }
 
    // function should print the topView of
    // the binary tree
    void TopView(Node root)
    {
        Queue q = new Queue();
        SortedDictionary<int, Node> topViewMap
            = new SortedDictionary<int, Node>();
 
        if (root == null) {
            return;
        }
        else {
            q.Enqueue(new QueueObj(root, 0));
        }
 
        // count function returns 1 if the container
        // contains an element whose key is equivalent
        // to hd, or returns zero otherwise.
        while (q.Count != 0) {
            QueueObj tmpNode = (QueueObj)q.Dequeue();
 
            if (!topViewMap.ContainsKey(tmpNode.hd)) {
                topViewMap[tmpNode.hd] = tmpNode.node;
            }
 
            if (tmpNode.node.left != null) {
                q.Enqueue(new QueueObj(tmpNode.node.left,
                                       tmpNode.hd - 1));
            }
            if (tmpNode.node.right != null) {
                q.Enqueue(new QueueObj(tmpNode.node.right,
                                       tmpNode.hd + 1));
            }
        }
 
        foreach(var entry in topViewMap.Values)
        {
            Console.Write(entry.data);
              Console.Write(" ");
        }
    }
 
    // Driver code
    public static void Main(string[] args)
    {
 
        /* Create following Binary Tree
            1
           / \
          2   3
           \
            4
             \
              5
               \
                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);
 
        Console.WriteLine("The top view of the tree is : ");
 
        tree.TopView(tree.root);
    }
}
 
// This code is contributed by rutvik_56


Javascript




<script>
// Javascript program to print top
// view of binary tree
 
class Node
{
    constructor(data)
    {
        this.data=data;
        this.left = this.right = null;
        this.hd = 0;
    }
}
 
// Driver Code
function topview(root)
{
    if(root == null)
        return;
    let q = [];
    let m = new Map();
    let hd = 0;
    root.hd = hd;
    q.push(root);
     
    while(q.length!=0)
    {
        root = q[0];
        hd = root.hd;
        if(!m.has(hd))
            m.set(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.shift()
    }
     
    let arr = Array.from(m);
    arr.sort(function(a,b){return a[0]-b[0];})
     
    for (let [key, value] of arr.values())
    {
        document.write(value+" ");
    }
}
 
let root = new Node(1)
root.left = new Node(2)
root.right = new Node(3)
root.left.right = new Node(4)
root.left.right.right = new Node(5)
root.left.right.right.right = new Node(6)
document.write("Following are nodes in top",
      "view of Binary Tree<br>")
topview(root)
 
// This code is contributed by avanitrachhadiya2155
</script>


Output

The top view of the tree is : 
2 1 3 6 

Time complexity: O(N * log(N)), where N is the number of nodes in the given tree.
Auxiliary Space: O(N), As we store nodes in the map and queue.

Above approach using HashMap for Java

Since we need the horizontal distance in sorted order TreeMap was used in the above solution; but instead, a minimum and maximum horizontal distance variable can be maintained for each iteration. After that traverse from minimum to the maximum while printing the first acquired node during the traversal of the tree that was stored in the map. Since, each horizontal distance from minimum to maximum is guaranteed to have at least one node in the map

Below is the implementation of the above approach:

C++




// C++ Program for the above approach
 
#include<bits/stdc++.h>
using namespace std;
 
struct Node{
    int data;
    Node* left;
    Node* right;
    Node(int data){
        this->data = data;
        this->left = NULL;
        this->right = NULL;
    }
};
 
struct QueueObj{
    Node* node;
    int hd;
    QueueObj(Node *node, int hd){
        this->node = node;
        this->hd = hd;
    }
};
 
void topView(Node* root){
    if(root == NULL) return;
     
    queue<QueueObj*> q;
    map<int, int> mp;
    int mn = 0;
    int mx = 0;
    // Level Order Traversal
    q.push(new QueueObj(root, 0));
    while(!q.empty()){
        QueueObj* curr = q.front();
        q.pop();
         
        // only include in map if this is the
        // first node of this specific
        // horizontal distance
        if(mp.find(curr->hd) == mp.end()){
            mp[curr->hd] = curr->node->data;
        }
         
        if(curr->node->left != NULL){
            // min can be found only in left side due to
            // "-1" minimum horizontal distance of any
            // node from root
            mn = min(mn, curr->hd-1);
            q.push(new QueueObj(curr->node->left, curr->hd-1));
        }
         
        if(curr->node->right != NULL){
            // max can be found only in right side due to
            // "+1" maximum horizontal distance of any
            // node from root
            mx = max(mx, curr->hd+1);
            q.push(new QueueObj(curr->node->right, curr->hd+1));
        }
    }
     
    // traversal of (horizontal distance from rooo)
    // minimum to maximum
    for(; mn<=mx; mn++){
        cout<<mp[mn]<<" ";
    }
    cout<<endl;
}
 
int main(){
    Node* root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->right = new Node(4);
    root->left->right->right = new Node(5);
    root->left->right->right->right = new Node(6);
    cout<<"Following are nodes in top view of Binary Tree"<<endl;
    topView(root);
    return 0;
}
 
// This code is contributed by Yash Agarwal(yashagarwal2852002)


Java




// Java program for the above approach
 
import java.util.*;
 
class GFG {
    // Structure of binary tree
    static class Node {
        Node left;
        Node right;
        int data;
 
        Node(int data)
        {
            this.left = this.right = null;
            this.data = data;
        }
    }
 
    // Queue Object Structure
    static class QueueObj {
        Node node;
        int hd;
 
        QueueObj(Node node, int hd)
        {
            this.node = node;
            this.hd = hd;
        }
    }
 
    static void topView(Node root)
    {
        if (root == null)
            return;
 
        Queue<QueueObj> q = new LinkedList<>();
        Map<Integer, Integer> map = new HashMap<>();
        int min = 0;
        int max = 0;
        // Level Order Traversal
        q.add(new QueueObj(root, 0));
        while (!q.isEmpty()) {
            QueueObj curr = q.poll();
 
            // only include in map if this is the
            // first node of this specific
            // horizontal distance
            if (!map.containsKey(curr.hd)) {
                map.put(curr.hd, curr.node.data);
            }
 
            if (curr.node.left != null) {
                // min can be found only in left side due to
                // "-1" minimum horizontal distance of any
                // node from root
                min = Math.min(min, curr.hd - 1);
                q.add(new QueueObj(curr.node.left,
                                   curr.hd - 1));
            }
 
            if (curr.node.right != null) {
                // max can be found only in right side due
                // to "+1" maximum horizontal distance of
                // any node from root
                max = Math.max(max, curr.hd + 1);
                q.add(new QueueObj(curr.node.right,
                                   curr.hd + 1));
            }
        }
 
        // traversal of (horizontal distance from root)
        // minimum to maximum
        for (; min <= max; min++) {
            System.out.print(map.get(min) + " ");
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.right = new Node(4);
        root.left.right.right = new Node(5);
        root.left.right.right.right = new Node(6);
        System.out.println("Following are nodes in"
                           + " top view of Binary Tree");
        topView(root);
    }
}
// Code Contributed by Animesh Singh


Python3




# Python code for the above approach
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
class QueueObj:
    def __init__(self, node, hd):
        self.node = node
        self.hd = hd
 
def topView(root):
    if root is None:
        return
 
    q = []
    mp = {}
    mn = 0
    mx = 0
    # Level Order Traversal
    q.append(QueueObj(root, 0))
    while len(q) != 0:
        curr = q.pop(0)
 
        # only include in map if this is the
        # first node of this specific
        # horizontal distance
        if curr.hd not in mp:
            mp[curr.hd] = curr.node.data
 
        if curr.node.left is not None:
            # min can be found only in left side due to
            # "-1" minimum horizontal distance of any
            # node from root
            mn = min(mn, curr.hd-1)
            q.append(QueueObj(curr.node.left, curr.hd-1))
 
        if curr.node.right is not None:
            # max can be found only in right side due to
            # "+1" maximum horizontal distance of any
            # node from root
            mx = max(mx, curr.hd+1)
            q.append(QueueObj(curr.node.right, curr.hd+1))
 
    # traversal of (horizontal distance from rooo)
    # minimum to maximum
    for hd in range(mn, mx+1):
        print(mp[hd],end=" ")
 
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.right = Node(4)
root.left.right.right = Node(5)
root.left.right.right.right = Node(6)
print("Following are nodes in top view of Binary Tree")
topView(root)
 
# This code is contributed by lokeshpotta20.


C#




// C# program for the above approach
 
using System;
using System.Collections.Generic;
 
public class GFG {
  // Structure of binary tree
  public class Node {
    public Node left;
    public Node right;
    public int data;
 
    public Node(int data)
    {
      this.left = this.right = null;
      this.data = data;
    }
  }
 
  // Queue Object Structure
  public class QueueObj {
    public Node node;
    public int hd;
 
    public QueueObj(Node node, int hd)
    {
      this.node = node;
      this.hd = hd;
    }
  }
 
  static void topView(Node root)
  {
    if (root == null)
      return;
 
    Queue<QueueObj> q = new Queue<QueueObj>();
    Dictionary<int, int> map
      = new Dictionary<int, int>();
    int min = 0;
    int max = 0;
    // Level Order Traversal
    q.Enqueue(new QueueObj(root, 0));
    while (q.Count != 0) {
      QueueObj curr = q.Dequeue();
 
      // only include in map if this is the
      // first node of this specific
      // horizontal distance
      if (!map.ContainsKey(curr.hd)) {
        map.Add(curr.hd, curr.node.data);
      }
 
      if (curr.node.left != null) {
        // min can be found only in left side due to
        // "-1" minimum horizontal distance of any
        // node from root
        min = Math.Min(min, curr.hd - 1);
        q.Enqueue(new QueueObj(curr.node.left,
                               curr.hd - 1));
      }
 
      if (curr.node.right != null) {
        // max can be found only in right side due
        // to "+1" maximum horizontal distance of
        // any node from root
        max = Math.Max(max, curr.hd + 1);
        q.Enqueue(new QueueObj(curr.node.right,
                               curr.hd + 1));
      }
    }
 
    // traversal of (horizontal distance from root)
    // minimum to maximum
    for (; min <= max; min++) {
      Console.Write(map[min] + " ");
    }
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.right = new Node(4);
    root.left.right.right = new Node(5);
    root.left.right.right.right = new Node(6);
    Console.WriteLine("Following are nodes in"
                      + " top view of Binary Tree");
    topView(root);
  }
}
 
// This code is contributed by karandeep1234


Javascript




// JavaScript program for the above approach
class Node{
    constructor(data){
        this.data = data;
        this.left = null;
        this.right = null;
    }
}
 
class QueueObj{
    constructor(node, hd){
        this.node = node;
        this.hd = hd;
    }
}
 
function topView(root){
    if(root == null) return;
     
    let q = [];
    let mp = new Map();
    let mn = 0;
    let mx = 0;
    // Level Order Traversal
    q.push(new QueueObj(root, 0));
    while(q.length != 0){
        let curr = q.shift();
         
        // only include in map if this is the
        // first node of this specific
        // horizontal distance
        if(mp[curr.hd] == null){
            mp[curr.hd] = curr.node.data;
        }
         
        if(curr.node.left != null){
            // min can be found only in left side due to
            // "-1" minimum horizontal distance of any
            // node from root
            mn = Math.min(mn, curr.hd-1);
            q.push(new QueueObj(curr.node.left, curr.hd-1));
        }
         
        if(curr.node.right != null){
            // max can be found only in right side due to
            // "+1" maximum horizontal distance of any
            // node from root
            mx = Math.max(mx, curr.hd+1);
            q.push(new QueueObj(curr.node.right, curr.hd+1));
        }
    }
    // traversal of (horizontal distance from rooo)
    // minimum to maximum
    while(mn <= mx){
        console.log(mp[mn]);
        mn++;
    }
}
 
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.right = new Node(4);
root.left.right.right = new Node(5);
root.left.right.right.right = new Node(6);
console.log("Following are nodes in top view of Binary Tree");
topView(root);
 
// This code is contributed by Yash Agarwal(yashagarwal2852002).


Output

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

Time Complexity: O(N), Since we only perform level-order traversal and print some part of the N nodes which at max will be 2N in case of skew tree
Auxiliary Space: O(N), Since we store the nodes in the map and queue.

Approach: To solve the problem follow the below idea: 

Here we use the two variables, one for the vertical distance of the 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 the depth of the new node is lower or higher with respect to the current node with the same vertical distance in the map. If the depth of the new node is lower, then we replace it

Follow the below steps to solve the problem:

  • Create a map of the type <int, pair<int, int>> and two variables d and l to store horizontal and vertical distance from the root respectively
  • Call the function to print the top view
  • If the root is equal to the null value then return from the function (Base case)
  • Check if this value of d is not present in the map, then set map[d] equal to {root->data, l}
  • Check if this value of d is already present and its vertical distance is greater than l, then set map[d] equal to {root->data, l}
  • Call this function recursively for (root->left, d-1, l+1, mp) and (root->right, d+1, l+1, mp)
  • Print the top view of the binary tree using the map

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#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 code
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 */


Java




// Java program to print top
// view of binary tree
import java.util.*;
 
class GFG {
 
    // Structure of binary tree
    static class Node {
        Node left;
        Node right;
        int data;
    }
 
    static class pair {
        int first, second;
 
        pair() {}
        pair(int i, int j)
        {
            first = i;
            second = j;
        }
    }
 
    // map to store the pair of node value and
    // its level with respect to the vertical
    // distance from root.
    static TreeMap<Integer, pair> m = new TreeMap<>();
 
    // function to create a new node
    static Node newNode(int key)
    {
        Node node = new Node();
        node.left = node.right = null;
        node.data = key;
        return node;
    }
 
    // function to fill the map
    static void fillMap(Node root, int d, int l)
    {
        if (root == null)
            return;
 
        if (m.get(d) == null) {
            m.put(d, new pair(root.data, l));
        }
        else if (m.get(d).second > l) {
            m.put(d, new pair(root.data, l));
        }
 
        fillMap(root.left, d - 1, l + 1);
        fillMap(root.right, d + 1, l + 1);
    }
 
    // function should print the topView of
    // the binary tree
    static void topView(Node root)
    {
        fillMap(root, 0, 0);
 
        for (Map.Entry<Integer, pair> entry :
             m.entrySet()) {
            System.out.print(entry.getValue().first + " ");
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        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);
        System.out.println("Following are nodes in"
                           + " top view of Binary Tree");
        topView(root);
    }
}
 
// This code is contributed by Arnab Kundu


Python3




# 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 print the 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


C#




// C# program to print top
// view of binary tree
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG {
 
    // Structure of binary tree
    class Node {
        public Node left;
        public Node right;
        public int data;
    }
 
    class pair {
        public int first, second;
 
        public pair(int i, int j)
        {
            first = i;
            second = j;
        }
    }
 
    // map to store the pair of node value and
    // its level with respect to the vertical
    // distance from root.
    static SortedDictionary<int, pair> m
        = new SortedDictionary<int, pair>();
 
    // function to create a new node
    static Node newNode(int key)
    {
        Node node = new Node();
        node.left = node.right = null;
        node.data = key;
        return node;
    }
 
    // function to fill the map
    static void fillMap(Node root, int d, int l)
    {
        if (root == null)
            return;
 
        if (!m.ContainsKey(d)) {
            m[d] = new pair(root.data, l);
        }
        else if (m[d].second > l) {
            m[d] = new pair(root.data, l);
        }
 
        fillMap(root.left, d - 1, l + 1);
        fillMap(root.right, d + 1, l + 1);
    }
 
    // function should print the topView of
    // the binary tree
    static void topView(Node root)
    {
        fillMap(root, 0, 0);
 
        foreach(pair entry in m.Values)
        {
            Console.Write(entry.first + " ");
        }
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        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);
        Console.WriteLine("Following are nodes in"
                          + " top view of Binary Tree");
        topView(root);
    }
}
 
// This code is contributed by pratham76


Javascript




<script>
// Javascript program to print top
// view of binary tree
 
// Structure of binary tree
class Node
{
    constructor()
    {
        this.data = 0;
        this.left = this.right = null;
    }
}
 
class pair
{
    constructor(i, j)
    {
        this.first = i;
        this.second = j;
    }
}
 
// map to store the pair of node value and
    // its level with respect to the vertical
    // distance from root.
let m = new Map();
     
// function to create a new node   
function newNode(key)
{
    let node = new Node();
        node.left = node.right = null;
        node.data = key;
        return node;
}
 
// function to fill the map
function fillMap(root, d, l)
{
    if (root == null)
            return;
  
        if (m.get(d) == null) {
            m.set(d, new pair(root.data, l));
        }
        else if (m.get(d).second > l) {
            m.set(d, new pair(root.data, l));
        }
  
        fillMap(root.left, d - 1, l + 1);
        fillMap(root.right, d + 1, l + 1);
}
 
// function should print the topView of
    // the binary tree
function topView(root)
{
    fillMap(root, 0, 0);
      
    let arr=Array.from(m.keys());
     
    arr.sort(function(a,b){return a-b;});
        for (let key of arr.values()) {
            document.write(m.get(key).first + " ");
        }
}
 
// Driver Code
let 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);
document.write("Following are nodes in"
                   + " top view of Binary Tree<br>");
topView(root);
 
// This code is contributed by rag2127
</script>


Output

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

Time complexity: O(N * log(N)), where N is the number of nodes in the given binary tree with each insertion operation in Map requiring O(log2 N) complexity.
Auxiliary Space: O(N)

Approach: Follow the below steps to solve the problem:

  • This approach is based on the level order traversal. We’ll keep a record of the current max so far left, and right horizontal distances from the root.
  • And if we found less distance (or greater in magnitude) than max left so far distance then update it and also push data on this node to a stack (stack is used because in level order traversal the left nodes will appear in reverse order)
  • If we found a greater distance then max right so far distance then update it and also push data on this node to a vector.
  • In this approach, no map is used.

Below is the implementation of the above approach:

C++14




// C++ Program to print Top View of a binary Tree
 
#include <bits/stdc++.h>
using namespace std;
 
// class for Tree node
class Node {
public:
    Node *left, *right;
    int data;
    Node() { left = right = 0; }
    Node(int data)
    {
        left = right = 0;
        this->data = data;
    }
};
 
/*
          1
         / \
        2   3
         \
          4
           \
            5
             \
              6
    Top view of the above binary tree is
    2 1 3 6
*/
 
// class for Tree
class Tree {
public:
    Node* root;
    Tree() { root = 0; }
 
    void topView()
    {
        // queue for holding nodes and their horizontal
        // distance from the root node
        queue<pair<Node*, int> > q;
 
        // pushing root node with distance 0
        q.push(make_pair(root, 0));
 
        // hd is current node's horizontal distance from
        // root node l is current left min horizontal
        // distance (or max in magnitude) so far from the
        // root node r is current right max horizontal
        // distance so far from the root node
 
        int hd = 0, l = 0, r = 0;
 
        // stack is for holding left node's data because
        // they will appear in reverse order that is why
        // using stack
        stack<int> left;
 
        // vector is for holding right node's data
        vector<int> right;
 
        Node* node;
 
        while (q.size()) {
 
            node = q.front().first;
            hd = q.front().second;
 
            if (hd < l) {
                left.push(node->data);
                l = hd;
            }
            else if (hd > r) {
                right.push_back(node->data);
                r = hd;
            }
 
            if (node->left) {
                q.push(make_pair(node->left, hd - 1));
            }
            if (node->right) {
                q.push(make_pair(node->right, hd + 1));
            }
 
            q.pop();
        }
        // printing the left node's data in reverse order
        while (left.size()) {
            cout << left.top() << " ";
            left.pop();
        }
 
        // then printing the root node's data
        cout << root->data << " ";
 
        // finally printing the right node's data
        for (auto x : right) {
            cout << x << " ";
        }
    }
};
 
// Driver code
int main()
{
    // Tree object
    Tree t;
    t.root = new Node(1);
    t.root->left = new Node(2);
    t.root->right = new Node(3);
    t.root->left->right = new Node(4);
    t.root->left->right->right = new Node(5);
    t.root->left->right->right->right = new Node(6);
    t.topView();
    cout << endl;
    return 0;
}


Java




// Java program to print top
// view of binary tree
import java.util.*;
 
class GFG {
 
    // Structure of binary tree
    static class Node {
        Node left;
        Node right;
        int data;
    }
    /*
              1
             / \
            2   3
             \
              4
               \
                5
                 \
                  6
        Top view of the above binary tree is
        2 1 3 6
    */
    static class pair {
        Node node;
        int hd;
 
        pair() {}
        pair(Node node, int hd)
        {
            this.node = node;
            this.hd = hd;
        }
    }
 
    // function to create a new node
    static 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
    static void topView(Node root)
    {
        // queue for holding nodes and their horizontal
        // distance from the root node
        Queue<pair> q = new LinkedList<>();
 
        // pushing root node with distance 0
        q.add(new pair(root, 0));
 
        // hd is current node's horizontal distance from
        // root node l is current left min horizontal
        // distance (or max in magnitude) so far from the
        // root node r is current right max horizontal
        // distance so far from the root node
 
        int hd = 0, l = 0, r = 0;
 
        // stack is for holding left node's data because
        // they will appear in reverse order that is why
        // using stack
 
        Stack<Integer> left = new Stack<>();
 
        // ArrayList is for holding right node's data
        ArrayList<Integer> right = new ArrayList<>();
        Node node = null;
 
        while (!q.isEmpty()) {
            node = q.peek().node;
            hd = q.peek().hd;
 
            if (hd < l) {
                left.push(node.data);
                l = hd;
            }
 
            if (hd > r) {
                right.add(node.data);
                r = hd;
            }
 
            if (node.left != null) {
                q.add(new pair(node.left, hd - 1));
            }
            if (node.right != null) {
                q.add(new pair(node.right, hd + 1));
            }
 
            q.poll();
        }
 
        // printing the left node's data in reverse order
        while (!left.isEmpty()) {
            System.out.print(left.peek() + " ");
            left.pop();
        }
 
        // then printing the root node's data
        System.out.print(root.data + " ");
 
        // finally printing the right node's data
        for (int d : right) {
            System.out.print(d + " ");
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        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);
        topView(root);
    }
}
 
// This code is contributed by Snigdha Patil


Python3




# Python3 Program to print Top View of a binary Tree
 
# Class of tree node
 
 
class Node:
    def __init__(self, data):
        self.left = None
        self.right = None
        self.data = data
 
 
'''
          1
         / \
        2   3
         \
          4
          \
            5
             \
              6
    Top view of the above binary tree is
    2 1 3 6
'''
 
# class for Tree
 
 
class Tree:
    def __init__(self):
        self.root = None
 
    def topView(self):
 
        # queue for holding nodes and their horizontal
        # distance from the root node
        q = []
 
        # pushing root node with distance 0
        q.append((self.root, 0))
 
        # hd is current node's horizontal distance from
        #  root node l is current left min horizontal
        #  distance (or max in magnitude) so far from the
        #  root node r is current right max horizontal
        # distance so far from the root node
 
        hd = 0
        l = 0
        r = 0
 
        # stack is for holding left node's data because
        # they will appear in reverse order that is why
        # using stack
        left = []
 
        # list is for holding right node's data
        right = []
 
        while len(q) > 0:
            node, hd = q[0]
 
            if hd < l:
                left.append(node.data)
                l = hd
 
            elif hd > r:
                right.append(node.data)
                r = hd
 
            if node.left != None:
                q.append((node.left, hd-1))
 
            if node.right != None:
                q.append((node.right, hd+1))
            q.pop(0)
 
        # printing the left node's data in reverse order
        while len(left) > 0:
            x = left.pop()
            print(x, end=" ")
 
        # then printing the root node's data
        print(self.root.data, end=" ")
 
        # finally printing the right node's data
        for x in right:
            print(x, end=" ")
 
 
# Driver code
if __name__ == '__main__':
    # Tree object
    t = Tree()
    t.root = Node(1)
    t.root.left = Node(2)
    t.root.right = Node(3)
    t.root.left.right = Node(4)
    t.root.left.right.right = Node(5)
    t.root.left.right.right.right = Node(6)
    t.topView()
 
    print()
 
# This code is contributed by Tapesh(tapeshdua420)


C#




// C# program to print top
// view of binary tree
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG {
 
  // Structure of binary tree
  public class Node {
    public Node left, right;
    public int data;
  }
  /*
              1
             / \
            2   3
             \
              4
               \
                5
                 \
                  6
        Top view of the above binary tree is
        2 1 3 6
    */
  public class pair {
    public Node node;
    public int hd;
 
    public pair() {}
    public pair(Node node, int hd)
    {
      this.node = node;
      this.hd = hd;
    }
  }
 
  // function to create a new node
  static 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
  static void topView(Node root)
  {
 
    // queue for holding nodes and their horizontal
    // distance from the root node
    Queue<pair> q = new Queue<pair>();
 
    // pushing root node with distance 0
    q.Enqueue(new pair(root, 0));
 
    // hd is current node's horizontal distance from
    // root node l is current left min horizontal
    // distance (or max in magnitude) so far from the
    // root node r is current right max horizontal
    // distance so far from the root node
    int hd = 0, l = 0, r = 0;
 
    // stack is for holding left node's data because
    // they will appear in reverse order that is why
    // using stack
    Stack<int> left = new Stack<int>();
 
    // ArrayList is for holding right node's data
    List<int> right = new List<int>();
    Node node = null;
 
    while (q.Count != 0) {
      node = q.Peek().node;
      hd = q.Peek().hd;
 
      if (hd < l) {
        left.Push(node.data);
        l = hd;
      }
 
      if (hd > r) {
        right.Add(node.data);
        r = hd;
      }
 
      if (node.left != null) {
        q.Enqueue(new pair(node.left, hd - 1));
      }
      if (node.right != null) {
        q.Enqueue(new pair(node.right, hd + 1));
      }
 
      q.Dequeue();
    }
 
    // printing the left node's data in reverse order
    while (left.Count != 0) {
      Console.Write(left.Peek() + " ");
      left.Pop();
    }
 
    // then printing the root node's data
    Console.Write(root.data + " ");
 
    // finally printing the right node's data
    foreach(int d in right) { Console.Write(d + " "); }
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    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);
    topView(root);
  }
}
 
// This code is contributed by karandeep1234.


Javascript




// JavaScript Program to print the Top view of binary tree
 
// A binary tree node has data, pointer to left child
// and a pointer to right child
class Node{
    constructor(data){
        this.data = data;
        this.left = null;
        this.right = null;
    }
}
 
class pair{
    constructor(val1, val2){
        this.first = val1;
        this.second = val2;
    }
}
 
/*
      1
     / \
    2   3
     \
      4
       \
        5
         \
          6
Top view of the above binary tree is
2 1 3 6
*/
 
function topView(root){
    // queue for holding nodes and their horizontal
    // distance from the root node
    let q = [];
     
    // pushing root node with distance 0
    q.push(new pair(root, 0));
 
    // hd is current node's horizontal distance from
    // root node l is current left min horizontal
    // distance (or max in magnitude) so far from the
    // root node r is current right max horizontal
    // distance so far from the root node
 
    let hd = 0, l = 0, r = 0;  
     
    // stack is for holding left node's data because
    // they will appear in reverse order that is why
    // using stack
    let left = [];
     
    // vector is for holding right node's data
    let right = [];
     
    let node;
     
    while(q.length > 0){
        let temp = q.shift();
         
        node = temp.first;
        hd = temp.second;
        if(hd < l){
            left.push(node.data);
            l = hd;
        }
        else if(hd > r){
            right.push(node.data);
            r = hd;
        }
         
        if(node.left != null){
            q.push(new pair(node.left, hd - 1));
        }
        if(node.right != null){
            q.push(new pair(node.right, hd + 1));
        }
    }
    // printing the left node's data in reverse order
    while(left.length > 0){
        document.write(left.pop() + " ");
    }
     
    // then printing the root node's data
    document.write(root.data + " ");
 
    // finally printing the right node's data
    for (let i = 0; i<right.length; i++) {
        document.write(right[i] + " ");
    }
}
 
// Driver Code
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.right = new Node(4);
root.left.right.right = new Node(5);
root.left.right.right.right = new Node(6);
topView(root);
 
// This code is contributed by Yash Agarwal(yashagarwal2852002)


Output

2 1 3 6 

Time Complexity: O(N), where N is the number of nodes in the given binary tree.
Auxiliary Space: O(N)

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 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments