Bottom View of a Binary Tree - GeeksforGeeks

02 Jul, 2021
Given a Binary Tree, we need to print the bottom view from left to right. A node x is there in output if x is the bottommost 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. 
Examples: 
                      20
                    /    \
                  8       22
                /   \      \
              5      3      25
                    / \      
                  10    14
For the above tree the output should be 5, 10, 3, 14, 25.If there are multiple bottom-most nodes for a horizontal distance from root, then print the later one in level traversal. For example, in the below diagram, 3 and 4 are both the bottom-most nodes at horizontal distance 0, we need to print 4. 
                   
                      20
                    /    \
                  8       22
                /   \    /   \
              5      3 4     25
                    / \      
                  10    14
For the above tree the output should be 5, 10, 4, 14, 25. 
Method 1 – Using Queue The following are steps to print Bottom View of Binary Tree. 1. We put tree nodes in a queue for the level order traversal. 2. Start with the horizontal distance(hd) 0 of the root node, keep on adding left child to queue along with the horizontal distance as hd-1 and right child as hd+1. 3. Also, use a TreeMap which stores key value pair sorted on key. 4. Every time, we encounter a new horizontal distance or an existing horizontal distance put the node data for the horizontal distance as key. For the first time it will add to the map, next time it will replace the value. This will make sure that the bottom most element for that horizontal distance is present in the map and if you see the tree from beneath that you will see that element.
Below is the implementation of the above:
C++
Java
Python3
C#
Javascript
// C++ Program to print Bottom View of Binary Tree#include<bits/stdc++.h>using namespace std; // Tree node classstruct Node{    int data; //data of the node    int hd; //horizontal distance of the node    Node *left, *right; //left and right references     // Constructor of tree node    Node(int key)    {        data = key;        hd = INT_MAX;        left = right = NULL;    }}; // Method that prints the bottom view.void bottomView(Node *root){    if (root == NULL)        return;     // Initialize a variable 'hd' with 0    // for the root element.    int hd = 0;     // TreeMap which stores key value pair    // sorted on key value    map<int, int> m;     // Queue to store tree nodes in level    // order traversal    queue<Node *> q;     // Assign initialized horizontal distance    // value to root node and add it to the queue.    root->hd = hd;    q.push(root);  // In STL, push() is used enqueue an item     // Loop until the queue is empty (standard    // level order loop)    while (!q.empty())    {        Node *temp = q.front();        q.pop();   // In STL, pop() is used dequeue an item         // Extract the horizontal distance value        // from the dequeued tree node.        hd = temp->hd;         // Put the dequeued tree node to TreeMap        // having key as horizontal distance. Every        // time we find a node having same horizontal        // distance we need to replace the data in        // the map.        m[hd] = temp->data;         // If the dequeued node has a left child, add        // it to the queue with a horizontal distance hd-1.        if (temp->left != NULL)        {            temp->left->hd = hd-1;            q.push(temp->left);        }         // If the dequeued node has a right child, add        // it to the queue with a horizontal distance        // hd+1.        if (temp->right != NULL)        {            temp->right->hd = hd+1;            q.push(temp->right);        }    }     // Traverse the map elements using the iterator.    for (auto i = m.begin(); i != m.end(); ++i)        cout << i->second << " ";} // Driver Codeint main(){    Node *root = new Node(20);    root->left = new Node(8);    root->right = new Node(22);    root->left->left = new Node(5);    root->left->right = new Node(3);    root->right->left = new Node(4);    root->right->right = new Node(25);    root->left->right->left = new Node(10);    root->left->right->right = new Node(14);    cout << "Bottom view of the given binary tree :\n"    bottomView(root);    return 0;}
// Java Program to print Bottom View of Binary Treeimport java.util.*;import java.util.Map.Entry; // Tree node classclass Node{    int data; //data of the node    int hd; //horizontal distance of the node    Node left, right; //left and right references     // Constructor of tree node    public Node(int key)    {        data = key;        hd = Integer.MAX_VALUE;        left = right = null;    }} //Tree classclass Tree{    Node root; //root node of tree     // Default constructor    public Tree() {}     // Parameterized tree constructor    public Tree(Node node)    {        root = node;    }     // Method that prints the bottom view.    public void bottomView()    {        if (root == null)            return;         // Initialize a variable 'hd' with 0 for the root element.        int hd = 0;         // TreeMap which stores key value pair sorted on key value        Map<Integer, Integer> map = new TreeMap<>();          // Queue to store tree nodes in level order traversal        Queue<Node> queue = new LinkedList<Node>();         // Assign initialized horizontal distance value to root        // node and add it to the queue.        root.hd = hd;        queue.add(root);         // Loop until the queue is empty (standard level order loop)        while (!queue.isEmpty())        {            Node temp = queue.remove();             // Extract the horizontal distance value from the            // dequeued tree node.            hd = temp.hd;             // Put the dequeued tree node to TreeMap having key            // as horizontal distance. Every time we find a node            // having same horizontal distance we need to replace            // the data in the map.            map.put(hd, temp.data);             // If the dequeued node has a left child add it to the            // queue with a horizontal distance hd-1.            if (temp.left != null)            {                temp.left.hd = hd-1;                queue.add(temp.left);            }            // If the dequeued node has a right child add it to the            // queue with a horizontal distance hd+1.            if (temp.right != null)            {                temp.right.hd = hd+1;                queue.add(temp.right);            }        }         // Extract the entries of map into a set to traverse        // an iterator over that.        Set<Entry<Integer, Integer>> set = map.entrySet();         // Make an iterator        Iterator<Entry<Integer, Integer>> iterator = set.iterator();         // Traverse the map elements using the iterator.        while (iterator.hasNext())        {            Map.Entry<Integer, Integer> me = iterator.next();            System.out.print(me.getValue()+" ");        }    }} // Main driver classpublic class BottomView{    public static void main(String[] args)    {        Node root = new Node(20);        root.left = new Node(8);        root.right = new Node(22);        root.left.left = new Node(5);        root.left.right = new Node(3);        root.right.left = new Node(4);        root.right.right = new Node(25);        root.left.right.left = new Node(10);        root.left.right.right = new Node(14);        Tree tree = new Tree(root);        System.out.println("Bottom view of the given binary tree:");        tree.bottomView();    }}
# Python3 program to print Bottom# View of Binary Tree  # Tree node classclass Node:         def __init__(self, key):                 self.data = key        self.hd = 1000000        self.left = None        self.right = None  # Method that prints the bottom view.def bottomView(root):     if (root == None):        return         # Initialize a variable 'hd' with 0    # for the root element.    hd = 0         # TreeMap which stores key value pair    # sorted on key value    m = dict()      # Queue to store tree nodes in level    # order traversal    q = []      # Assign initialized horizontal distance    # value to root node and add it to the queue.    root.hd = hd         # In STL, append() is used enqueue an item    q.append(root)       # Loop until the queue is empty (standard    # level order loop)    while (len(q) != 0):        temp = q[0]                 # In STL, pop() is used dequeue an item        q.pop(0)                  # Extract the horizontal distance value        # from the dequeued tree node.        hd = temp.hd          # Put the dequeued tree node to TreeMap        # having key as horizontal distance. Every        # time we find a node having same horizontal        # distance we need to replace the data in        # the map.        m[hd] = temp.data          # If the dequeued node has a left child, add        # it to the queue with a horizontal distance hd-1.        if (temp.left != None):            temp.left.hd = hd - 1            q.append(temp.left)          # If the dequeued node has a right child, add        # it to the queue with a horizontal distance        # hd+1.        if (temp.right != None):            temp.right.hd = hd + 1            q.append(temp.right)      # Traverse the map elements using the iterator.    for i in sorted(m.keys()):        print(m[i], end = ' ')         # Driver Codeif __name__=='__main__':         root = Node(20)    root.left = Node(8)    root.right = Node(22)    root.left.left = Node(5)    root.left.right = Node(3)    root.right.left = Node(4)    root.right.right = Node(25)    root.left.right.left = Node(10)    root.left.right.right = Node(14)         print("Bottom view of the given binary tree :")         bottomView(root)     # This code is contributed by rutvik_56
// C# program to print Bottom View of Binary Treeusing System;using System.Collections;using System.Collections.Generic;  // Tree node classclass Node{         // Data of the node    public int data;         // Horizontal distance of the node    public int hd;         // left and right references    public Node left, right;         // Constructor of tree node    public Node(int key)    {        data = key;        hd = 1000000;        left = right = null;    }} // Tree classclass Tree{         // Root node of tree    Node root;         // Default constructor    public Tree(){}         // Parameterized tree constructor    public Tree(Node node)    {        root = node;    }      // Method that prints the bottom view.    public void bottomView()    {        if (root == null)            return;                     // Initialize a variable 'hd' with        // 0 for the root element.        int hd = 0;          // TreeMap which stores key value        // pair sorted on key value        SortedDictionary<int,                         int> map = new SortedDictionary<int,                                                         int>();          // Queue to store tree nodes in level order        // traversal        Queue queue = new Queue();                 // Assign initialized horizontal distance        // value to root node and add it to the queue.        root.hd = hd;        queue.Enqueue(root);          // Loop until the queue is empty        // (standard level order loop)        while (queue.Count != 0)        {            Node temp = (Node) queue.Dequeue();              // Extract the horizontal distance value            // from the dequeued tree node.            hd = temp.hd;              // Put the dequeued tree node to TreeMap            // having key as horizontal distance.            // Every time we find a node having same            // horizontal distance we need to replace            // the data in the map.            map[hd] = temp.data;              // If the dequeued node has a left child            // add it to the queue with a horizontal            // distance hd-1.            if (temp.left != null)            {                temp.left.hd = hd - 1;                queue.Enqueue(temp.left);            }                         // If the dequeued node has a right            // child add it to the queue with a            // horizontal distance hd+1.            if (temp.right != null)            {                temp.right.hd = hd + 1;                queue.Enqueue(temp.right);            }        }                 foreach(int i in map.Values)        {            Console.Write(i + " ");        }    }}  public class BottomView{   // Driver codepublic static void Main(string[] args){    Node root = new Node(20);    root.left = new Node(8);    root.right = new Node(22);    root.left.left = new Node(5);    root.left.right = new Node(3);    root.right.left = new Node(4);    root.right.right = new Node(25);    root.left.right.left = new Node(10);    root.left.right.right = new Node(14);    Tree tree = new Tree(root);         Console.WriteLine("Bottom view of the " +                      "given binary tree:");         tree.bottomView();}} // This code is contributed by pratham76
<script>       // JavaScript program to print Bottom View of Binary Tree      // Tree node class      class Node {        // Constructor of tree node        constructor(key) {          this.data = key; // Data of the node          this.hd = 1000000; // Horizontal distance of the node          this.left = null; // left and right references          this.right = null;        }      }       // Tree class      class Tree {        // Parameterized tree constructor        constructor(node) {          // Root node of tree          this.root = node;        }         // Method that prints the bottom view.        bottomView() {          if (this.root == null) return;           // Initialize a variable 'hd' with          // 0 for the root element.          var hd = 0;           // TreeMap which stores key value          // pair sorted on key value          var map = {};           // Queue to store tree nodes in level order          // traversal          var queue = [];           // Assign initialized horizontal distance          // value to root node and add it to the queue.          this.root.hd = hd;          queue.push(this.root);           // Loop until the queue is empty          // (standard level order loop)          while (queue.length != 0) {            var temp = queue.shift();             // Extract the horizontal distance value            // from the dequeued tree node.            hd = temp.hd;             // Put the dequeued tree node to TreeMap            // having key as horizontal distance.            // Every time we find a node having same            // horizontal distance we need to replace            // the data in the map.            map[hd] = temp.data;             // If the dequeued node has a left child            // add it to the queue with a horizontal            // distance hd-1.            if (temp.left != null) {              temp.left.hd = hd - 1;              queue.push(temp.left);            }             // If the dequeued node has a right            // child add it to the queue with a            // horizontal distance hd+1.            if (temp.right != null) {              temp.right.hd = hd + 1;              queue.push(temp.right);            }          }           for (const [key, value] of Object.entries(map).sort(            (a, b) => a[0] - b[0]          )) {            document.write(value + " ");          }        }      }       // Driver code      var root = new Node(20);      root.left = new Node(8);      root.right = new Node(22);      root.left.left = new Node(5);      root.left.right = new Node(3);      root.right.left = new Node(4);      root.right.right = new Node(25);      root.left.right.left = new Node(10);      root.left.right.right = new Node(14);      var tree = new Tree(root);       document.write("Bottom view of the " + "given binary tree:<br>");       tree.bottomView();       </script>
Output: 
Bottom view of the given binary tree:
5 10 4 14 25
Method 2- Using HashMap() This method is contributed by Ekta Goel. 
Approach: Create a map like, map where key is the horizontal distance and value is a pair(a, b) where a is the value of the node and b is the height of the node. Perform a pre-order traversal of the tree. If the current node at a horizontal distance of h is the first we’ve seen, insert it in the map. Otherwise, compare the node with the existing one in map and if the height of the new node is greater, update in the Map.
Below is the implementation of the above:
C++
Java
Python3
// C++ Program to print Bottom View of Binary Tree#include <bits/stdc++.h>#include <map>using namespace std; // Tree node classstruct Node{    // data of the node    int data;         // horizontal distance of the node    int hd;         //left and right references    Node * left, * right;         // Constructor of tree node    Node(int key)    {        data = key;        hd = INT_MAX;        left = right = NULL;    }}; void printBottomViewUtil(Node * root, int curr, int hd, map <int, pair <int, int>> & m){    // Base case    if (root == NULL)        return;         // If node for a particular    // horizontal distance is not    // present, add to the map.    if (m.find(hd) == m.end())    {        m[hd] = make_pair(root -> data, curr);    }    // Compare height for already    // present node at similar horizontal    // distance    else    {        pair < int, int > p = m[hd];        if (p.second <= curr)        {            m[hd].second = curr;            m[hd].first = root -> data;        }    }         // Recur for left subtree    printBottomViewUtil(root -> left, curr + 1, hd - 1, m);         // Recur for right subtree    printBottomViewUtil(root -> right, curr + 1, hd + 1, m);} void printBottomView(Node * root){         // Map to store Horizontal Distance,    // Height and Data.    map < int, pair < int, int > > m;         printBottomViewUtil(root, 0, 0, m);          // Prints the values stored by printBottomViewUtil()    map < int, pair < int, int > > ::iterator it;    for (it = m.begin(); it != m.end(); ++it)    {        pair < int, int > p = it -> second;        cout << p.first << " ";    }} int main(){    Node * root = new Node(20);    root -> left = new Node(8);    root -> right = new Node(22);    root -> left -> left = new Node(5);    root -> left -> right = new Node(3);    root -> right -> left = new Node(4);    root -> right -> right = new Node(25);    root -> left -> right -> left = new Node(10);    root -> left -> right -> right = new Node(14);    cout << "Bottom view of the given binary tree :\n";    printBottomView(root);    return 0;}
// Java program to print Bottom View of Binary Treeimport java.io.*;import java.lang.*;import java.util.*; class GFG{ // Tree node classstatic class Node{         // Data of the node    int data;     // Horizontal distance of the node    int hd;     // Left and right references    Node left, right;     // Constructor of tree node    public Node(int key)    {        data = key;        hd = Integer.MAX_VALUE;        left = right = null;    }} static void printBottomViewUtil(Node root, int curr, int hd,                                TreeMap<Integer, int[]> m){         // Base case    if (root == null)        return;     // If node for a particular    // horizontal distance is not    // present, add to the map.    if (!m.containsKey(hd))    {        m.put(hd, new int[]{ root.data, curr });    }         // Compare height for already    // present node at similar horizontal    // distance    else    {        int[] p = m.get(hd);        if (p[1] <= curr)        {            p[1] = curr;            p[0] = root.data;        }        m.put(hd, p);    }     // Recur for left subtree    printBottomViewUtil(root.left, curr + 1,                        hd - 1, m);     // Recur for right subtree    printBottomViewUtil(root.right, curr + 1,                        hd + 1, m);} static void printBottomView(Node root){     // Map to store Horizontal Distance,    // Height and Data.    TreeMap<Integer, int[]> m = new TreeMap<>();     printBottomViewUtil(root, 0, 0, m);     // Prints the values stored by printBottomViewUtil()    for(int val[] : m.values())    {        System.out.print(val[0] + " ");    }} // Driver Codepublic static void main(String[] args){    Node root = new Node(20);    root.left = new Node(8);    root.right = new Node(22);    root.left.left = new Node(5);    root.left.right = new Node(3);    root.right.left = new Node(4);    root.right.right = new Node(25);    root.left.right.left = new Node(10);    root.left.right.right = new Node(14);     System.out.println(        "Bottom view of the given binary tree:");     printBottomView(root);}} // This code is contributed by Kingash
# Python3 program to print Bottom# View of Binary Treeclass Node:         def __init__(self, key = None,                      left = None,                     right = None):                                  self.data = key        self.left = left        self.right = right         def printBottomView(root):           # Create a dictionary where    # key -> relative horizontal distance    # of the node from root node and    # value -> pair containing node's    # value and its level    d = dict()         printBottomViewUtil(root, d, 0, 0)         # Traverse the dictionary in sorted    # order of their keys and print    # the bottom view    for i in sorted(d.keys()):        print(d[i][0], end = " ") def printBottomViewUtil(root, d, hd, level):           # Base case    if root is None:        return         # If current level is more than or equal    # to maximum level seen so far for the    # same horizontal distance or horizontal    # distance is seen for the first time,    # update the dictionary    if hd in d:        if level >= d[hd][1]:            d[hd] = [root.data, level]    else:        d[hd] = [root.data, level]             # recur for left subtree by decreasing    # horizontal distance and increasing    # level by 1    printBottomViewUtil(root.left, d, hd - 1,                                   level + 1)         # recur for right subtree by increasing    # horizontal distance and increasing    # level by 1    printBottomViewUtil(root.right, d, hd + 1,                                    level + 1) # Driver Code   if __name__ == '__main__':         root = Node(20)    root.left = Node(8)    root.right = Node(22)    root.left.left = Node(5)    root.left.right = Node(3)    root.right.left = Node(4)    root.right.right = Node(25)    root.left.right.left = Node(10)    root.left.right.right = Node(14)         print("Bottom view of the given binary tree :")         printBottomView(root) # This code is contributed by tusharroy
YouTubeGeeksforGeeks502K subscribersBottom View of a Binary Tree | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 4:45•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=fPhgtqKdG5k" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
tusharroy
pratham76
rutvik_56
Kingash
rdtank
Accolite
Amazon
CouponDunia
Flipkart
Paytm
tree-view
Walmart
Tree
Paytm
Flipkart
Accolite
Amazon
Walmart
CouponDunia
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Inorder Tree Traversal without Recursion
Binary Tree | Set 3 (Types of Binary Tree)
Binary Tree | Set 2 (Properties)
Decision Tree
A program to check if a binary tree is BST or not
Complexity of different operations in Binary tree, Binary Search Tree and AVL tree
Construct Tree from given Inorder and Preorder traversals
Introduction to Tree Data Structure
Lowest Common Ancestor in a Binary Tree | Set 1
BFS vs DFS for Binary Tree