Open In App

Sum of nodes in bottom view of Binary Tree

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary tree, the task is to print the sum of nodes in the bottom view of the given Binary Tree. The bottom view of a binary tree is the set of nodes visible when the tree is viewed from the bottom. 

Examples: 

Input : 
1
/ \
2 3
/ \ \
4 5 6
Output : 20
Input :
1
/ \
2 3
\
4
\
5
\
6
Output : 17

Approach: The idea is to use a queue. 

  • Put tree nodes in a queue for the level order traversal
  • 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.
  • Use a map to store the hd value(as key) and the last node(as pair) having the corresponding hd value.
  • 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.
  • Finally, traverse the map and calculate the sum of all the elements.

Below is the implementation of the above approach:

C++




// C++ implementation of the above approach
#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 that returns the sum of
// nodes in bottom view of binary tree
int SumOfBottomView(Node* root)
{
    if (root == NULL)
        return 0;
    queue<Node*> q;
 
    unordered_map<int, int> m;
    int hd = 0;
    root->hd = hd;
 
    int sum = 0;
 
    // Push node and horizontal distance to queue
    q.push(root);
 
    while (q.size()) {
        Node* temp = q.front();
        q.pop();
 
        hd = temp->hd;
 
        // Put the dequeued tree node to Map
        // 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 (temp->left) {
            temp->left->hd = hd - 1;
            q.push(temp->left);
        }
        if (temp->right) {
            temp->right->hd = hd + 1;
            q.push(temp->right);
        }
    }
 
    unordered_map<int, int>::iterator itr;
 
    // Sum up all the nodes in bottom view of the tree
    for (itr = m.begin(); itr != m.end(); itr++)
        sum += itr->second;
 
    return sum;
}
 
// Driver Code
int main()
{
    Node* root = newNode(20);
    root->left = newNode(8);
    root->right = newNode(22);
    root->left->left = newNode(5);
    root->left->right = newNode(3);
    root->right->left = newNode(4);
    root->right->right = newNode(25);
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(14);
 
    cout << SumOfBottomView(root);
 
    return 0;
}


Java




// Java implementation of
// the above approach
import java.util.*;
 
class GFG{
     
// Structure of binary tree
public static class Node
{
    public Node left;
    public Node right;
    public int hd;
    public int data;
};
   
// Function to create
// a new node
static Node newNode(int key)
{
    Node node = new Node();
    node.data = key;
    node.left = null;
    node.right = null;
    return node;
}
   
// Function that returns the sum of
// nodes in bottom view of binary tree
static int SumOfBottomView(Node root)
{
    if (root == null)
        return 0;
     
    Queue<Node> q = new LinkedList<>();
     
    HashMap<Integer,
            Integer> m = new HashMap<Integer,
                                     Integer>();
    int hd = 0;
    root.hd = hd;
    int sum = 0;
     
    // Push node and horizontal
    // distance to queue
    q.add(root);
     
    while (q.size() != 0)
    {
        Node temp = q.poll();
        hd = temp.hd;
         
        // Put the dequeued tree node
        // to Map 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.put(hd, temp.data);
         
        if (temp.left != null)
        {
            temp.left.hd = hd - 1;
            q.add(temp.left);
        }
        if (temp.right != null)
        {
            temp.right.hd = hd + 1;
            q.add(temp.right);
        }
    }   
     
    // Sum up all the nodes in
    // bottom view of the tree   
    for(int value : m.values())
    {
        sum += value;
    }
    return sum;
}
   
// Driver code
public static void main(String[] args)
{
    Node root = newNode(20);
    root.left = newNode(8);
    root.right = newNode(22);
    root.left.left = newNode(5);
    root.left.right = newNode(3);
    root.right.left = newNode(4);
    root.right.right = newNode(25);
    root.left.right.left = newNode(10);
    root.left.right.right = newNode(14);
     
    System.out.println(SumOfBottomView(root));
}
}
 
// This code is contributed by pratham76


Python3




# Python3 implementation of the above approach
 
class Node:
     
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
        self.hd = None
 
# Function that returns the Sum of
# nodes in bottom view of binary tree
def SumOfBottomView(root):
 
    if root == None:
        return 0
     
    q = []
    m = {}
    hd, Sum = 0, 0
    root.hd = hd
 
    # Push node and horizontal
    # distance to queue
    q.append(root)
 
    while len(q) > 0:
        temp = q.pop(0)
        hd = temp.hd
 
        # Put the dequeued tree node to Map
        # 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 temp.left != None:
            temp.left.hd = hd - 1
            q.append(temp.left)
         
        if temp.right != None:
            temp.right.hd = hd + 1
            q.append(temp.right)
 
    # Sum up all the nodes in bottom
    # view of the tree
    for itr in m:
        Sum += m[itr]
 
    return Sum
 
# 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(SumOfBottomView(root))
     
# This code is contributed by Rituraj Jain


C#




// C# implementation of
// the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
// Structure of binary tree
public class Node
{
  public Node left;
  public Node right;
  public int hd;
  public int data;
};
  
// Function to create
// a new node
static Node newNode(int key)
{
  Node node = new Node();
  node.data = key;
  node.left = null;
  node.right = null;
  return node;
}
  
// Function that returns the sum of
// nodes in bottom view of binary tree
static int SumOfBottomView(Node root)
{
  if (root == null)
    return 0;
 
  Queue q = new Queue();
  Dictionary<int,
             int> m = new Dictionary<int,
                                     int>();
  int hd = 0;
  root.hd = hd;
  int sum = 0;
 
  // Push node and horizontal
  // distance to queue
  q.Enqueue(root);
 
  while (q.Count != 0)
  {
    Node temp = (Node)q.Peek();
    q.Dequeue();
    hd = temp.hd;
 
    // Put the dequeued tree node
    // to Map 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 (temp.left != null)
    {
      temp.left.hd = hd - 1;
      q.Enqueue(temp.left);
    }
    if (temp.right != null)
    {
      temp.right.hd = hd + 1;
      q.Enqueue(temp.right);
    }
  }   
   
  // Sum up all the nodes in
  // bottom view of the tree   
  foreach(KeyValuePair<int,
                       int> itr in m)
  {
    sum += itr.Value;
  }
  return sum;
}
  
// Driver code
public static void Main(string[] args)
{
  Node root = newNode(20);
  root.left = newNode(8);
  root.right = newNode(22);
  root.left.left = newNode(5);
  root.left.right = newNode(3);
  root.right.left = newNode(4);
  root.right.right = newNode(25);
  root.left.right.left = newNode(10);
  root.left.right.right = newNode(14);
  Console.Write(SumOfBottomView(root));
}
}
 
// This code is contributed by rutvik_56


Javascript




<script>
 
    // JavaScript implementation of the approach
     
    // Structure of binary tree
    class Node
    {
        constructor(key) {
           this.left = null;
           this.right = null;
           this.data = key;
           this.hd;
        }
    }
     
    // Function to create
    // a new node
    function newNode(key)
    {
        let node = new Node(key);
        return node;
    }
 
    // Function that returns the sum of
    // nodes in bottom view of binary tree
    function SumOfBottomView(root)
    {
        if (root == null)
            return 0;
 
        let q = [];
 
        let m = new Map();
        let hd = 0;
        root.hd = hd;
        let sum = 0;
 
        // Push node and horizontal
        // distance to queue
        q.push(root);
 
        while (q.length != 0)
        {
            let temp = q[0];
            q.shift();
            hd = temp.hd;
 
            // Put the dequeued tree node
            // to Map 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.set(hd, temp.data);
 
            if (temp.left != null)
            {
                temp.left.hd = hd - 1;
                q.push(temp.left);
            }
            if (temp.right != null)
            {
                temp.right.hd = hd + 1;
                q.push(temp.right);
            }
        }  
 
        // Sum up all the nodes in
        // bottom view of the tree
        m.forEach((value,key)=>{
          sum += value;
        })
        return sum;
    }
     
    let root = newNode(20);
    root.left = newNode(8);
    root.right = newNode(22);
    root.left.left = newNode(5);
    root.left.right = newNode(3);
    root.right.left = newNode(4);
    root.right.right = newNode(25);
    root.left.right.left = newNode(10);
    root.left.right.right = newNode(14);
      
    document.write(SumOfBottomView(root));
 
</script>


Output

58






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

Another Approach(Using Depth First Search):

Create a map where the key is the horizontal distance and the 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 into the map. Otherwise, compare the node with the existing one in map and if the height of the new node is greater, update the Map.

Follow the below steps to solve the above problem:

1) Recursively apply Depth first search on the Tree starting from root node and keep a track of height curr and horizontal distance as hd of the current node with respect to root node as root node’s height is 0.
2) If there’s no node as value for horizontal distance hd in map then set map[hd] = make_pair(root -> data, curr). Else store the pair value of mp[hd] in p. Then If p.second <= curr then set m[hd].second = curr and m[hd].first = root -> data
3) Call depth first search for left node of root node with height curr + 1 and horizontal distance as hd – 1 and right node of root node with height curr + 1 and horizontal distance as hd + 1
4) Base case would be to return when root is NULL.

Below is the implementation of above approach:

C++




// C++ Program to print the sum of nodes in Bottom View of Binary Tree
#include <bits/stdc++.h>
using namespace std;
 
// Tree node class
struct Node{
    int data;
    int hd;
    Node *left;
    Node* right;
};
 
// Function to create a new node
Node* newNode(int key){
    Node* node = new Node();
    node->left = node->right = NULL;
    node->data = key;
    return node;
}
 
void SumOfBottomViewUtil(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
    SumOfBottomViewUtil(root -> left, curr + 1, hd - 1, m);
    // Recur for right subtree
    SumOfBottomViewUtil(root -> right, curr + 1, hd + 1, m);
}
 
int SumOfBottomView(Node * root){
    // Map to store Horizontal Distance, Height and Data.
    map < int, pair < int, int > > m;
    SumOfBottomViewUtil(root, 0, 0, m);
     
    // Prints the values stored by SumOfBottomViewUtil()
    map < int, pair < int, int > > ::iterator it;
    int sum = 0;
    for (it = m.begin(); it != m.end(); ++it){
        pair < int, int > p = it -> second;
        sum += p.first;
    }
    return sum;
}
 
// Main Function
int main(){
    Node* root = newNode(20);
    root->left = newNode(8);
    root->right = newNode(22);
    root->left->left = newNode(5);
    root->left->right = newNode(3);
    root->right->left = newNode(4);
    root->right->right = newNode(25);
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(14);
     
    cout<<SumOfBottomView(root);
    return 0;
}
 
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Java




import java.util.*;
 
// Tree node class
class Node {
    int data;
    int hd;
    Node left, right;
 
    // Constructor
    public Node(int key) {
        data = key;
        left = right = null;
    }
}
 
public class BottomViewSum {
    // Function to create a new node
    static Node newNode(int key) {
        return new Node(key);
    }
 
    // Utility function to calculate the sum of nodes in the Bottom View
    static int sumOfBottomView(Node root) {
        // Map to store Horizontal Distance, Height, and Data
        Map<Integer, Pair<Integer, Integer>> map = new TreeMap<>();
        sumOfBottomViewUtil(root, 0, 0, map);
 
        // Calculate the sum of values stored by sumOfBottomViewUtil
        int sum = 0;
        for (Map.Entry<Integer, Pair<Integer, Integer>> entry : map.entrySet()) {
            Pair<Integer, Integer> p = entry.getValue();
            sum += p.getKey();
        }
        return sum;
    }
 
    // Recursive utility function to calculate Bottom View
    static void sumOfBottomViewUtil(Node root, int curr, int hd,
                                    Map<Integer, Pair<Integer, Integer>> map) {
        // Base case
        if (root == null)
            return;
 
        // If node for a particular horizontal distance
        // is not present, add to the map.
        if (!map.containsKey(hd))
            map.put(hd, new Pair<>(root.data, curr));
 
        // Compare height for an already present node at a similar horizontal distance
        else {
            Pair<Integer, Integer> p = map.get(hd);
            if (p.getValue() <= curr) {
                p.setValue(curr);
                p.setKey(root.data);
            }
        }
 
        // Recur for left subtree
        sumOfBottomViewUtil(root.left, curr + 1, hd - 1, map);
        // Recur for right subtree
        sumOfBottomViewUtil(root.right, curr + 1, hd + 1, map);
    }
 
    // Main Function
    public static void main(String[] args) {
        Node root = newNode(20);
        root.left = newNode(8);
        root.right = newNode(22);
        root.left.left = newNode(5);
        root.left.right = newNode(3);
        root.right.left = newNode(4);
        root.right.right = newNode(25);
        root.left.right.left = newNode(10);
        root.left.right.right = newNode(14);
 
        System.out.println(sumOfBottomView(root));
    }
}
 
// Pair class to store two values
class Pair<T, U> {
    private T first;
    private U second;
 
    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }
 
    public T getKey() {
        return first;
    }
 
    public void setKey(T first) {
        this.first = first;
    }
 
    public U getValue() {
        return second;
    }
 
    public void setValue(U second) {
        this.second = second;
    }
}


Python3




# Tree node class
class Node:
    def __init__(self, key):
        self.data = key
        self.hd = 0
        self.left = None
        self.right = None
 
# Function to create a new node
def newNode(key):
    return Node(key)
 
# Function to calculate the sum of nodes in the Bottom View of the Binary Tree
def sumOfBottomView(root):
    if root is None:
        return 0
     
    # Dictionary to store horizontal distance, height, and data
    m = {}
     
    # Helper function to calculate the horizontal distance, height, and data
    def sumOfBottomViewUtil(root, curr, hd):
        nonlocal m
         
        if root is None:
            return
         
        # If node for a particular horizontal distance is not present, add to the dictionary
        if hd not in m:
            m[hd] = [root.data, curr]
        # Compare height for already present node at similar horizontal distance
        else:
            p = m[hd]
            if p[1] <= curr:
                m[hd][1] = curr
                m[hd][0] = root.data
         
        # Recur for left subtree
        sumOfBottomViewUtil(root.left, curr + 1, hd - 1)
        # Recur for right subtree
        sumOfBottomViewUtil(root.right, curr + 1, hd + 1)
     
    # Call the helper function to calculate horizontal distance, height, and data
    sumOfBottomViewUtil(root, 0, 0)
     
    # Calculate the sum of the bottom view nodes
    total_sum = 0
    for key in m:
        total_sum += m[key][0]
     
    return total_sum
 
# Main Function
if __name__ == "__main__":
    root = newNode(20)
    root.left = newNode(8)
    root.right = newNode(22)
    root.left.left = newNode(5)
    root.left.right = newNode(3)
    root.right.left = newNode(4)
    root.right.right = newNode(25)
    root.left.right.left = newNode(10)
    root.left.right.right = newNode(14)
     
    print(sumOfBottomView(root))


C#




using System;
using System.Collections.Generic;
 
// Tree node class
public class Node
{
    public int data;
    public int hd;
    public Node left, right;
}
 
public class BinaryTree
{
    // Function to create a new node
    public Node newNode(int key)
    {
        Node node = new Node();
        node.left = node.right = null;
        node.data = key;
        return node;
    }
 
    // Helper function to calculate the sum of nodes in the bottom view
    private void SumOfBottomViewUtil(Node root, int curr,
                                     int hd, Dictionary<int, Tuple<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.ContainsKey(hd))
        {
            m[hd] = new Tuple<int, int>(root.data, curr);
        }
        else
        {
            // Compare height for already present node at similar horizontal distance
            var p = m[hd];
            if (p.Item2 <= curr)
            {
                m[hd] = new Tuple<int, int>(root.data, curr);
            }
        }
 
        // Recur for left subtree
        SumOfBottomViewUtil(root.left, curr + 1, hd - 1, m);
        // Recur for right subtree
        SumOfBottomViewUtil(root.right, curr + 1, hd + 1, m);
    }
 
    // Function to calculate the sum of nodes in the bottom view
    public int SumOfBottomView(Node root)
    {
        // Dictionary to store Horizontal Distance, Height, and Data
        Dictionary<int, Tuple<int, int>> m = new Dictionary<int, Tuple<int, int>>();
        SumOfBottomViewUtil(root, 0, 0, m);
 
        // Calculate and print the sum
        int sum = 0;
        foreach (var pair in m)
        {
            var p = pair.Value;
            sum += p.Item1;
        }
        return sum;
    }
 
    // Main Function
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
        Node root = tree.newNode(20);
        root.left = tree.newNode(8);
        root.right = tree.newNode(22);
        root.left.left = tree.newNode(5);
        root.left.right = tree.newNode(3);
        root.right.left = tree.newNode(4);
        root.right.right = tree.newNode(25);
        root.left.right.left = tree.newNode(10);
        root.left.right.right = tree.newNode(14);
 
        Console.WriteLine(tree.SumOfBottomView(root));
    }
}


Javascript




// JavaScript program to print the sum of nodes in Bottom View of Binary Tree
 
// Tree node class
class Node {
    constructor(data) {
        this.data = data;
        this.hd = 0;
        this.left = null;
        this.right = null;
    }
}
 
// Function to create a new node
function newNode(key) {
    const node = new Node(key);
    return node;
}
 
// Function to calculate the sum of nodes in Bottom View
function sumOfBottomView(root) {
    // Map to store Horizontal Distance, Height, and Data
    const m = new Map();
 
    // Utility function to calculate the Bottom View
    function sumOfBottomViewUtil(curr, hd, height, m) {
        // Base case
        if (curr === null) return;
 
        // If node for a particular horizontal distance
        // is not present, add to the map
        if (!m.has(hd) || m.get(hd).height <= height) {
            m.set(hd, { data: curr.data, height });
        }
 
        // Recur for left subtree
        sumOfBottomViewUtil(curr.left, hd - 1, height + 1, m);
 
        // Recur for right subtree
        sumOfBottomViewUtil(curr.right, hd + 1, height + 1, m);
    }
 
    // Call utility function to calculate Bottom View
    sumOfBottomViewUtil(root, 0, 0, m);
 
    // Calculate the sum from the values stored in the map
    let sum = 0;
    for (const [key, value] of m) {
        sum += value.data;
    }
 
    return sum;
}
 
// Main Function
function main() {
    const root = newNode(20);
    root.left = newNode(8);
    root.right = newNode(22);
    root.left.left = newNode(5);
    root.left.right = newNode(3);
    root.right.left = newNode(4);
    root.right.right = newNode(25);
    root.left.right.left = newNode(10);
    root.left.right.right = newNode(14);
 
    console.log(sumOfBottomView(root));
}
 
// Call the main function
main();
 
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Output

58






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



Last Updated : 07 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads