Open In App

Print Nodes in Top View of Binary Tree

Last Updated : 23 Dec, 2024
Summarize
Comments
Improve
Suggest changes
Share
177 Likes
Like
Report

Given a binary tree. The task is to find the top view of the binary tree. The top view of a binary tree is the set of nodes visible when the tree is viewed from the top.

Note: 

  • Return the nodes from the leftmost node to the rightmost node.
  • If two nodes are at the same position (horizontal distance) and are outside the shadow of the tree, consider the leftmost node only. 

Examples:

Example 1: The Green colored nodes represents the top view in the below Binary tree.

top_view_example1


Example 2: The Green colored nodes represents the top view in the below Binary tree.

Print-Nodes-in-Top-View-of-Binary-Tree-4
Top view for example 2

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++
// C++ program to print top
// view of binary tree
// using dfs

#include <bits/stdc++.h>
using namespace std;

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);
}

// DFS Approach to find 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
  //     1
  //    / \
  //   2   3
  //  / \ / \
  // 4  5 6  7

    Node* root = new Node(1);
    root->left = new Node(2);       
    root->right = new Node(3);            
    root->left->left = new Node(4);     
    root->left->right = new Node(5);   
    root->right->left = new Node(6);   
    root->right->right = new Node(7); 

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java Python C# JavaScript

Output
4 2 1 3 7 

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++
// C++ program to print top
// view of binary tree
// using bfs
#include <bits/stdc++.h>
using namespace std;

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

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

// Function to return the top view of a binary tree
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;

    // Start BFS with the root node at 
    // horizontal distance 0
    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
    //    / \
    //   2   3
    //  / \ / \
    // 4  5 6  7

    Node* root = new Node(1);
    root->left = new Node(2);       
    root->right = new Node(3);            
    root->left->left = new Node(4);     
    root->left->right = new Node(5);   
    root->right->left = new Node(6);   
    root->right->right = new Node(7); 

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java Python C# JavaScript

Output
4 2 1 3 7 

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

A queue is used to perform level-order traversal, storing each node along with its corresponding horizontal distance from the root. hashmap keeps track of the topmost node at every horizontal distance. During traversal, if a node at a given horizontal distance is encountered for the first time, it is added to the map.

Additionally, the minimum horizontal distance (mn) is updated to organize the result. After completing the traversal, the map's values are transferred to a result array, adjusting indices based on mn to ensure the nodes are arranged correctly from leftmost to rightmost in the top view. BFS approach ensures that nodes closer to the root and encountered first are prioritized in the top view.

C++
// C++ program to print top view of binary tree
// optimally using bfs

#include <bits/stdc++.h>
using namespace std;

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

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

// Function to return a list of nodes visible
// from the top view from left to right in Binary Tree.
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
    //     1
    //    / \
    //   2   3
    //  / \ / \
    // 4  5 6  7

    Node *root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(6);
    root->right->right = new Node(7);

    vector<int> result = topView(root);
    for (int i : result) {
        cout << i << " ";
    }
    return 0;
}
Java Python C# JavaScript

Output
4 2 1 3 7 

Top View of Binary Tree
Visit Course explore course icon

Similar Reads