Top View of Binary Tree

Last Updated : 8 Oct, 2025

Given the root of a binary tree, find the top view of the tree.
The top view of a binary tree represents the set of nodes visible when the tree is viewed from above.

Each node in the tree has a horizontal distance (HD) from the root, which helps determine its position when viewed from the top:

  • The root node has an HD of 0.
  • The left child of a node has an HD equal to parent’s HD - 1.
  • The right child of a node has an HD equal to parent’s HD + 1.

Note:

  • The result should contain the nodes visible from leftmost to rightmost and if two nodes have the same horizontal distance, only the uppermost (first encountered) node should be considered in the top view.

Examples:

Input:

420046834

Output: [2, 1, 3]
Explanation: The Green colored nodes represents the top view in the below Binary tree.

420046833

Input:

4200466772

Output: [40, 20, 10, 30, 100]
Explanation: The Green colored nodes represents the top view in the below Binary tree.

Print-Nodes-in-Top-View-of-Binary-Tree-4
Try it on GfG Practice
redirect icon

[Approach 1] Using DFS - O(n * log n) Time and O(n) Space

The idea is to use a Depth-First Search (DFS) approach to find the top view of a binary tree. We keep track of horizontal distance from root node. Start from the root node with a distance of 0. When we move to left child we subtract 1 and add 1 when we move to right child to distance of the current node. We use a HashMap to store the top most node that appears at a given horizontal distance. As we traverse the tree, we check if there is any node at current distance in hashmap. If it's the first node encountered at its horizontal distance ,we include it in the top view.

C++
#include <iostream>
#include<vector>
#include<map>
using namespace std;

// Node Structure
class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

// DFS Helper to store top view nodes
void dfs(Node* node, int hd, int level, 
         map<int, pair<int, int>>& topNodes) {
  
    if (!node) return;

    // If horizontal distance is encountered for 
    // the first time or if it's at a higher level
    if (topNodes.find(hd) == topNodes.end() || 
        topNodes[hd].second > level) {
        topNodes[hd] = {node->data, level};
    }

    // Recur for left and right subtrees
    dfs(node->left, hd - 1, level + 1, topNodes);
    dfs(node->right, hd + 1, level + 1, topNodes);
}

// Finding the top view of a binary tree
vector<int> topView(Node* root) {
    vector<int> result;
    if (!root) return result;
    
    // Horizontal distance -> {node's value, level}
    map<int, pair<int, int>> topNodes; 
    
    // Start DFS traversal
    dfs(root, 0, 0, topNodes);

    // Collect nodes from the map
    for (auto it : topNodes) {
        result.push_back(it.second.first);
    }

    return result;
}


int main() {
    
  // Create a sample binary tree
  //     10
  //    /  \
  //   20   30
  //  / \   / \
  // 40  60 90  100

    Node* root = new Node(10);
    root->left = new Node(20);       
    root->right = new Node(30);            
    root->left->left = new Node(40);     
    root->left->right = new Node(60);   
    root->right->left = new Node(90);   
    root->right->right = new Node(100); 

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;

// Node Structure
class Node {
    int data;
    Node left;
    Node right;

    Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG {

    // DFS Helper to store top view nodes
    static void dfs(Node node, int hd, int level, Map<Integer, int[]> topNodes) {
        if (node == null) return;

        // If horizontal distance is encountered for 
        // the first time or if it's at a higher level
        if (!topNodes.containsKey(hd) || topNodes.get(hd)[1] > level) {
            topNodes.put(hd, new int[]{node.data, level});
        }

        // Recur for left and right subtrees
        dfs(node.left, hd - 1, level + 1, topNodes);
        dfs(node.right, hd + 1, level + 1, topNodes);
    }

    // Finding the top view of a binary tree
    static ArrayList<Integer> topView(Node root) {
        ArrayList<Integer> result = new ArrayList<>();
        if (root == null) return result;

        // Horizontal distance -> {node's value, level}
        TreeMap<Integer, int[]> topNodes = new TreeMap<>();

        // Start DFS traversal
        dfs(root, 0, 0, topNodes);

        // Collect nodes from the map
        for (Map.Entry<Integer, int[]> entry : topNodes.entrySet()) {
            result.add(entry.getValue()[0]);
        }

        return result;
    }

    public static void main(String[] args) {

        // Create a sample binary tree
        //     10
        //    /  \
        //   20   30
        //  / \   / \
        // 40  60 90  100

        Node root = new Node(10);
        root.left = new Node(20);       
        root.right = new Node(30);            
        root.left.left = new Node(40);     
        root.left.right = new Node(60);   
        root.right.left = new Node(90);   
        root.right.right = new Node(100); 

        ArrayList<Integer> result = topView(root);
        for (int i : result) {
            System.out.print(i + " ");
        }
    }
}
Python
# Node Structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

# DFS Helper to store top view nodes
def dfs(node, hd, level, topNodes):
    if node is None:
        return

    # If horizontal distance is encountered for 
    # the first time or if it's at a higher level
    if hd not in topNodes or topNodes[hd][1] > level:
        topNodes[hd] = (node.data, level)

    # Recur for left and right subtrees
    dfs(node.left, hd - 1, level + 1, topNodes)
    dfs(node.right, hd + 1, level + 1, topNodes)

# Finding the top view of a binary tree
def topView(root):
    result = []
    if root is None:
        return result

    # Horizontal distance -> (node's value, level)
    topNodes = dict()

    # Start DFS traversal
    dfs(root, 0, 0, topNodes)

    # Collect nodes from the map sorted by horizontal distance
    for hd in sorted(topNodes.keys()):
        result.append(topNodes[hd][0])

    return result

if __name__ == "__main__":

    # Create a sample binary tree
    #     10
    #    /  \
    #   20   30
    #  / \   / \
    # 40  60 90  100

    root = Node(10)
    root.left = Node(20)
    root.right = Node(30)
    root.left.left = Node(40)
    root.left.right = Node(60)
    root.right.left = Node(90)
    root.right.right = Node(100)

    result = topView(root)
    print(" ".join(map(str, result)))
C#
using System;
using System.Collections.Generic;

// Node Structure
class Node {
    public int data;
    public Node left, right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    
    // Finding the top view of a binary tree
    static void dfs(Node node, int hd, int level, SortedDictionary<int, int[]> topNodes) {
        if (node == null)
            return;

        // If horizontal distance is encountered for 
        // the first time or if it's at a higher level
        if (!topNodes.ContainsKey(hd) || topNodes[hd][1] > level)
        {
            topNodes[hd] = new int[] { node.data, level };
        }

        // Recur for left and right subtrees
        dfs(node.left, hd - 1, level + 1, topNodes);
        dfs(node.right, hd + 1, level + 1, topNodes);
    }

    // Finding the top view of a binary tree
    static List<int> topView(Node root) {
        List<int> result = new List<int>();
        if (root == null)
            return result;

        // Horizontal distance -> {node's value, level}
        SortedDictionary<int, int[]> topNodes = new SortedDictionary<int, int[]>();

        // Start DFS traversal
        dfs(root, 0, 0, topNodes);

        // Collect nodes from the map
        foreach (var kvp in topNodes) {
            result.Add(kvp.Value[0]);
        }

        return result;
    }

    static void Main(string[] args)
    {
        // Create a sample binary tree
        //     10
        //    /  \
        //   20   30
        //  / \   / \
        // 40  60 90  100

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.left = new Node(40);
        root.left.right = new Node(60);
        root.right.left = new Node(90);
        root.right.right = new Node(100);

        List<int> result = TopView(root);
        foreach (int i in result)
        {
            Console.Write(i + " ");
        }
    }
}
JavaScript
// Node Structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// DFS Helper to store top view nodes
function dfs(node, hd, level, topNodes) {
    if (node === null) return;

    // If horizontal distance is encountered for 
    // the first time or if it's at a higher level
    if (!(hd in topNodes) || topNodes[hd][1] > level) {
        topNodes[hd] = [node.data, level];
    }

    // Recur for left and right subtrees
    dfs(node.left, hd - 1, level + 1, topNodes);
    dfs(node.right, hd + 1, level + 1, topNodes);
}

// Finding the top view of a binary tree
function topView(root) {
    const result = [];
    if (root === null) return result;

    // Horizontal distance -> [node's value, level]
    const topNodes = {};

    // Start DFS traversal
    dfs(root, 0, 0, topNodes);

    // Collect nodes from the map sorted by horizontal distance
    const sortedKeys = Object.keys(topNodes).map(Number).sort((a, b) => a - b);
    for (const key of sortedKeys) {
        result.push(topNodes[key][0]);
    }

    return result;
}

// Driver Code

// Create a sample binary tree
//     10
//    /  \
//   20   30
//  / \   / \
// 40  60 90  100

const root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(60);
root.right.left = new Node(90);
root.right.right = new Node(100);

const result = topView(root);
console.log(result.join(" "));

Output
40 20 10 30 100 

[Approach 2] Using BFS - O(n * log n) Time and O(n) Space

The idea is similar to Vertical Order Traversal. Like vertical Order Traversal, we need to put nodes of the same horizontal distance together. We just do a level order traversal (bfs) instead of dfs so that the topmost node at a horizontal distance is visited before any other node of the same horizontal distance below it.

C++
#include <iostream>
#include<vector>
#include<queue>
#include<map>
using namespace std;

// Node Structure
class Node {
public:
    int data;   
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

vector<int> topView(Node *root) {
    vector<int> result;
    if (!root) return result;

    // Map to store the first node at each 
  	// horizontal distance (hd)
    map<int, int> topNodes;
    
    // Queue to store nodes along with their
    // horizontal distance
    queue<pair<Node*, int>> q;

    q.push({root, 0});

    while (!q.empty()) {
        
        auto nodeHd = q.front();
        
        // Current node
        Node *node = nodeHd.first;  
        
        // Current horizontal distance
        int hd = nodeHd.second;     
        q.pop();

        // If this horizontal distance is seen for the first
      	// time, store the node
        if (topNodes.find(hd) == topNodes.end()) {
            topNodes[hd] = node->data;
        }

        // Add left child to the queue with horizontal
      	// distance - 1
        if (node->left) {
            q.push({node->left, hd - 1});
        }

        // Add right child to the queue with 
        // horizontal distance + 1
        if (node->right) {
            q.push({node->right, hd + 1});
        }
    }

    // Extract the nodes from the map in sorted order 
  	// of their horizontal distances
    for (auto it : topNodes) {
        result.push_back(it.second);
    }

    return result;
}

int main() {
    
    // Create a sample binary tree
    //     1
    //    / \
    //   20   30
    //  / \  /  \
    // 40  60 90 100

    Node* root = new Node(10);
    root->left = new Node(20);       
    root->right = new Node(30);            
    root->left->left = new Node(40);     
    root->left->right = new Node(60);   
    root->right->left = new Node(90);   
    root->right->right = new Node(100); 

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.LinkedList;
import java.util.TreeMap;

// Node Structure
class Node {
    public int data;   
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG {

    static ArrayList<Integer> topView(Node root) {
        ArrayList<Integer> result = new ArrayList<>();
        if (root == null) return result;

        // Map to store the first node at each 
        // horizontal distance (hd)
        Map<Integer, Integer> topNodes = new TreeMap<>();

        // Queue to store nodes along with their
        // horizontal distance
        Queue<Object[]> q = new LinkedList<>();

        q.add(new Object[]{root, 0});

        while (!q.isEmpty()) {
            
            Object[] nodeHd = q.poll();

            // Current node
            Node node = (Node) nodeHd[0];

            // Current horizontal distance
            int hd = (int) nodeHd[1];

            // If this horizontal distance is seen for the first
            // time, store the node
            if (!topNodes.containsKey(hd)) {
                topNodes.put(hd, node.data);
            }

            // Add left child to the queue with horizontal
            // distance - 1
            if (node.left != null) {
                q.add(new Object[]{node.left, hd - 1});
            }

            // Add right child to the queue with 
            // horizontal distance + 1
            if (node.right != null) {
                q.add(new Object[]{node.right, hd + 1});
            }
        }

        // Extract the nodes from the map in sorted order 
        // of their horizontal distances
        for (Map.Entry<Integer, Integer> entry : topNodes.entrySet()) {
            result.add(entry.getValue());
        }

        return result;
    }

    public static void main(String[] args) {
        
        // Create a sample binary tree
        //     10
        //    / \
        //   20   30
        //  / \  /  \
        // 40  60 90 100

        Node root = new Node(10);
        root.left = new Node(20);       
        root.right = new Node(30);            
        root.left.left = new Node(40);     
        root.left.right = new Node(60);   
        root.right.left = new Node(90);   
        root.right.right = new Node(100); 

        List<Integer> result = topView(root);
        for (int i : result) {
            System.out.print(i + " ");
        }
    }
}
Python
from collections import deque

# Node Structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def topView(root):
    result = []
    if root is None:
        return result

    # Map to store the first node at each 
    # horizontal distance (hd)
    topNodes = {}

    # Queue to store nodes along with their
    # horizontal distance
    q = deque()
    
    q.append((root, 0))

    while q:
        node, hd = q.popleft()

        # If this horizontal distance is seen for the first
        # time, store the node
        if hd not in topNodes:
            topNodes[hd] = node.data

        # Add left child to the queue with horizontal
        # distance - 1
        if node.left:
            q.append((node.left, hd - 1))

        # Add right child to the queue with 
        # horizontal distance + 1
        if node.right:
            q.append((node.right, hd + 1))

    # Extract the nodes from the map in sorted order 
    # of their horizontal distances
    for hd in sorted(topNodes.keys()):
        result.append(topNodes[hd])

    return result

if __name__ == "__main__":

    # Create a sample binary tree
    #     10
    #    / \
    #   20   30
    #  / \  /  \
    # 40  60 90 100

    root = Node(10)
    root.left = Node(20)
    root.right = Node(30)
    root.left.left = Node(40)
    root.left.right = Node(60)
    root.right.left = Node(90)
    root.right.right = Node(100)

    result = topView(root)
    print(" ".join(map(str, result)))
C#
using System;
using System.Collections.Generic;

// Node Structure
class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    
    static List<int> topView(Node root) {
        List<int> result = new List<int>();
        if (root == null) return result;

        // Map to store the first node at each 
        // horizontal distance (hd)
        SortedDictionary<int, int> topNodes = new SortedDictionary<int, int>();

        // Queue to store nodes along with their
        // horizontal distance
        Queue<Tuple<Node, int>> q = new Queue<Tuple<Node, int>>();

        q.Enqueue(new Tuple<Node, int>(root, 0));

        while (q.Count > 0)
        {
            var nodeHd = q.Dequeue();

            // Current node
            Node node = nodeHd.Item1;

            // Current horizontal distance
            int hd = nodeHd.Item2;

            // If this horizontal distance is seen for the first
            // time, store the node
            if (!topNodes.ContainsKey(hd))
            {
                topNodes[hd] = node.data;
            }

            // Add left child to the queue with horizontal
            // distance - 1
            if (node.left != null)
            {
                q.Enqueue(new Tuple<Node, int>(node.left, hd - 1));
            }

            // Add right child to the queue with 
            // horizontal distance + 1
            if (node.right != null)
            {
                q.Enqueue(new Tuple<Node, int>(node.right, hd + 1));
            }
        }

        // Extract the nodes from the map in sorted order 
        // of their horizontal distances
        foreach (var kvp in topNodes)
        {
            result.Add(kvp.Value);
        }

        return result;
    }

    static void Main(string[] args) {
        
        // Create a sample binary tree
        //     10
        //    / \
        //   20   30
        //  / \   / \
        // 40  60 90 100

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.left = new Node(40);
        root.left.right = new Node(60);
        root.right.left = new Node(90);
        root.right.right = new Node(100);

        List<int> result = topView(root);
        foreach (int i in result)
        {
            Console.Write(i + " ");
        }
    }
}
JavaScript
// Node Structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function topView(root) {
    const result = [];
    if (!root) return result;

    // Map to store the first node at each 
    // horizontal distance (hd)
    const topNodes = {};

    // Queue to store nodes along with their
    // horizontal distance
    const q = [];
    
    q.push([root, 0]);

    while (q.length) {
        const [node, hd] = q.shift();

        // If this horizontal distance is seen for the first
        // time, store the node
        if (!(hd in topNodes)) {
            topNodes[hd] = node.data;
        }

        // Add left child to the queue with horizontal
        // distance - 1
        if (node.left) {
            q.push([node.left, hd - 1]);
        }

        // Add right child to the queue with 
        // horizontal distance + 1
        if (node.right) {
            q.push([node.right, hd + 1]);
        }
    }

    // Extract the nodes from the map in sorted order 
    // of their horizontal distances
    const sortedKeys = Object.keys(topNodes).map(Number).sort((a, b) => a - b);
    for (const key of sortedKeys) {
        result.push(topNodes[key]);
    }

    return result;
}

// Driver Code

// Sample binary tree
//     10
//    /  \
//   20   30
//  / \   / \
// 40 60 90 100

const root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(60);
root.right.left = new Node(90);
root.right.right = new Node(100);

const result = topView(root);
console.log(result.join(" "));

Output
40 20 10 30 100 

[Optimized Approach] Using BFS - O(n) Time and O(n) Space

The top view of a binary tree can be found using BFS. A queue stores each node with its horizontal distance from the root, while a hashmap keeps track of the first node seen at each distance. During traversal, nodes at new horizontal distances are added to the map, and the minimum distance is tracked. After traversal, the map’s values are transferred to a result array in order from leftmost to rightmost, ensuring that nodes closer to the root appear first in the top view.

C++
#include <iostream>
#include<vector>
#include<queue>
#include<unordered_map>
#include<climits>
using namespace std;

// Node Structure
class Node {
  public:
    int data;
    Node *left;
    Node *right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

vector<int> topView(Node *root) {
  
    // base case
    if (root ==  nullptr) {
        return {};
    }
    Node *temp = nullptr;
  
    // creating empty queue for level order traversal.
    queue<pair<Node *, int>> q;
  
    // creating a map to store nodes at a
    // particular horizontal distance.
    unordered_map<int, int> mp;

    int mn = INT_MAX;
    q.push({root, 0});
    while (!q.empty()) {
      
        temp = q.front().first;
        int d = q.front().second;
        mn = min(mn, d);
        q.pop();
      
        // storing temp->data in map.
        if (mp.find(d) == mp.end()) {
            mp[d] = temp->data;
        }
      
        // if left child of temp exists, pushing it in
        // the queue with the horizontal distance.
        if (temp->left) {
            q.push({temp->left, d - 1});
        }
      
        // if right child of temp exists, pushing it in
        // the queue with the horizontal distance.
        if (temp->right) {
            q.push({temp->right, d + 1});
        }
    }
    vector<int> ans(mp.size());
  
    // traversing the map and storing the nodes in list
    // at every horizontal distance.
    for (auto it = mp.begin(); it != mp.end(); it++) {
        ans[it->first - mn] = (it->second);
    }
  
    return ans;
}

int main() {

    // Create a sample binary tree
    //     10
    //    / \
    //   20  30
    //  / \   / \
    // 40  60 90  100

    Node *root = new Node(10);
    root->left = new Node(20);
    root->right = new Node(30);
    root->left->left = new Node(40);
    root->left->right = new Node(60);
    root->right->left = new Node(90);
    root->right->right = new Node(100);

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Map;

// Node Structure
class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

// Pair class to store node and its horizontal distance
class NodeHd {
    Node node;
    int hd;

    NodeHd(Node n, int h) {
        node = n;
        hd = h;
    }
}

class GFG {

    static ArrayList<Integer> topView(Node root) {
        ArrayList<Integer> ans = new ArrayList<>();
        if (root == null) return ans;

        // Queue for level order traversal storing node and horizontal distance
        Queue<NodeHd> q = new LinkedList<>();
        q.add(new NodeHd(root, 0));

        // Map to store first node at each horizontal distance
        Map<Integer, Integer> mp = new HashMap<>();
        int minHd = Integer.MAX_VALUE;

        while (!q.isEmpty()) {
            NodeHd temp = q.poll();
            Node node = temp.node;
            int hd = temp.hd;
            minHd = Math.min(minHd, hd);

            // store the first node encountered at this horizontal distance
            if (!mp.containsKey(hd)) {
                mp.put(hd, node.data);
            }

            if (node.left != null) q.add(new NodeHd(node.left, hd - 1));
            if (node.right != null) q.add(new NodeHd(node.right, hd + 1));
        }

        // convert map to list in order from leftmost to rightmost
        int maxHd = Integer.MIN_VALUE;
        for (int key : mp.keySet()) {
            maxHd = Math.max(maxHd, key);
        }

        for (int i = minHd; i <= maxHd; i++) {
            ans.add(mp.get(i));
        }

        return ans;
    }

    public static void main(String[] args) {

        // Create a sample binary tree
        //     10
        //    / \
        //   20  30
        //  / \   / \
        // 40  60 90  100

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.left = new Node(40);
        root.left.right = new Node(60);
        root.right.left = new Node(90);
        root.right.right = new Node(100);

        ArrayList<Integer> result = topView(root);
        for (int i : result) {
            System.out.print(i + " ");
        }
    }
}
Python
from collections import deque

# Node Structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def topView(root):
    
    # base case
    if root is None:
        return []
    temp = None

    # creating empty queue for level order traversal.
    q = deque()

    # creating a map to store nodes at a
    # particular horizontal distance.
    mp = {}

    mn = float('inf')
    q.append((root, 0))

    while q:
        temp, d = q.popleft()
        mn = min(mn, d)

        # storing temp.data in map.
        if d not in mp:
            mp[d] = temp.data

        # if left child of temp exists, pushing it in
        # the queue with the horizontal distance.
        if temp.left:
            q.append((temp.left, d - 1))

        # if right child of temp exists, pushing it in
        # the queue with the horizontal distance.
        if temp.right:
            q.append((temp.right, d + 1))

    ans = [0] * len(mp)

    # traversing the map and storing the nodes in list
    # at every horizontal distance.
    for key, val in mp.items():
        ans[key - mn] = val

    return ans


if __name__ == "__main__":

    # Create a sample binary tree
    #     10
    #    / \
    #   20  30
    #  / \   / \
    # 40  60 90  100

    root = Node(10)
    root.left = Node(20)
    root.right = Node(30)
    root.left.left = Node(40)
    root.left.right = Node(60)
    root.right.left = Node(90)
    root.right.right = Node(100)

    result = topView(root)
    print(" ".join(map(str, result)))
C#
using System;
using System.Collections.Generic;

// Node Structure
class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    
    static List<int> topView(Node root)
    {
        // base case
        if (root == null) return new List<int>();
        Node temp = null;

        // creating empty queue for level order traversal.
        Queue<Tuple<Node, int>> q = new Queue<Tuple<Node, int>>();

        // creating a map to store nodes at a
        // particular horizontal distance.
        Dictionary<int, int> mp = new Dictionary<int, int>();

        int mn = int.MaxValue;
        q.Enqueue(new Tuple<Node, int>(root, 0));

        while (q.Count > 0)
        {
            var nodeHd = q.Dequeue();
            temp = nodeHd.Item1;
            int d = nodeHd.Item2;
            mn = Math.Min(mn, d);

            // storing temp.data in map.
            if (!mp.ContainsKey(d))
            {
                mp[d] = temp.data;
            }

            // if left child of temp exists, pushing it in
            // the queue with the horizontal distance.
            if (temp.left != null) q.Enqueue(new Tuple<Node, int>(temp.left, d - 1));

            // if right child of temp exists, pushing it in
            // the queue with the horizontal distance.
            if (temp.right != null) q.Enqueue(new Tuple<Node, int>(temp.right, d + 1));
        }

        List<int> ans = new List<int>(new int[mp.Count]);

        // traversing the map and storing the nodes in list
        // at every horizontal distance.
        foreach (var kvp in mp)
        {
            ans[kvp.Key - mn] = kvp.Value;
        }

        return ans;
    }

    static void Main()
    {
        // Create a sample binary tree
        //     10
        //    / \
        //   20  30
        //  / \   / \
        // 40  60 90  100

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.left = new Node(40);
        root.left.right = new Node(60);
        root.right.left = new Node(90);
        root.right.right = new Node(100);

        List<int> result = topView(root);
        Console.WriteLine(string.Join(" ", result));
    }
}
JavaScript
// Node Structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function topView(root) {

    // base case
    if (root === null) return [];
    let temp = null;

    // creating empty queue for level order traversal.
    const q = [];

    // creating a map to store nodes at a
    // particular horizontal distance.
    const mp = {};

    let mn = Infinity;
    q.push([root, 0]);

    while (q.length > 0) {
        let [temp, d] = q.shift(); // destructure Node and hd correctly
        mn = Math.min(mn, d);

        // storing temp.data in map.
        if (!(d in mp)) {
            mp[d] = temp.data;
        }

        // if left child of temp exists, pushing it in
        // the queue with the horizontal distance.
        if (temp.left) {
            q.push([temp.left, d - 1]);
        }

        // if right child of temp exists, pushing it in
        // the queue with the horizontal distance.
        if (temp.right) {
            q.push([temp.right, d + 1]);
        }
    }

    const ans = new Array(Object.keys(mp).length);

    // traversing the map and storing the nodes in list
    // at every horizontal distance.
    for (const key in mp) {
        ans[key - mn] = mp[key];
    }

    return ans;
}

// Driver Code
  
    // Create a sample binary tree
        //     10
        //    / \
        //   20  30
        //  / \   / \
        // 40  60 90  100
const root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(60);
root.right.left = new Node(90);
root.right.right = new Node(100);

const result = topView(root);
console.log(result.join(" "));

Output
40 20 10 30 100 
Comment