Vertical Sum in a given Binary Tree | Set 1 - GeeksforGeeks

14 Feb, 2022
Given a Binary Tree, find the vertical sum of the nodes that are in the same vertical line. Print all sums through different vertical lines.Examples:  
      1
    /   \
  2      3
 / \    / \
4   5  6   7
The tree has 5 vertical linesVertical-Line-1 has only one node 4 => vertical sum is 4 Vertical-Line-2: has only one node 2=> vertical sum is 2 Vertical-Line-3: has three nodes: 1,5,6 => vertical sum is 1+5+6 = 12 Vertical-Line-4: has only one node 3 => vertical sum is 3 Vertical-Line-5: has only one node 7 => vertical sum is 7So expected output is 4, 2, 12, 3 and 7  
We need to check the Horizontal Distances from the root for all nodes. If two nodes have the same Horizontal Distance (HD), then they are on the same vertical line. The idea of HD is simple. HD for root is 0, a right edge (edge connecting to right subtree) is considered as +1 horizontal distance and a left edge is considered as -1 horizontal distance. For example, in the above tree, HD for Node 4 is at -2, HD for Node 2 is -1, HD for 5 and 6 is 0 and HD for node 7 is +2. We can do an in-order traversal of the given Binary Tree. While traversing the tree, we can recursively calculate HDs. We initially pass the horizontal distance as 0 for root. For left subtree, we pass the Horizontal Distance as Horizontal distance of root minus 1. For right subtree, we pass the Horizontal Distance as Horizontal Distance of root plus 1.Following is Java implementation for the same. HashMap is used to store the vertical sums for different horizontal distances. Thanks to Nages for suggesting this method.  
C++
Java
Python3
C#
Javascript
// C++ program to find Vertical Sum in// a given Binary Tree#include<bits/stdc++.h>using namespace std; struct Node{    int data;    struct Node *left, *right;}; // A utility function to create a new// Binary Tree nodeNode* newNode(int data){    Node *temp = new Node;    temp->data = data;    temp->left = temp->right = NULL;    return temp;} // Traverses the tree in in-order form and// populates a hashMap that contains the// vertical sumvoid verticalSumUtil(Node *node, int hd,                     map<int, int> &Map){    // Base case    if (node == NULL) return;     // Recur for left subtree    verticalSumUtil(node->left, hd-1, Map);     // Add val of current node to    // map entry of corresponding hd    Map[hd] += node->data;     // Recur for right subtree    verticalSumUtil(node->right, hd+1, Map);} // Function to find vertical sumvoid verticalSum(Node *root){    // a map to store sum of nodes for each    // horizontal distance    map < int, int> Map;    map < int, int> :: iterator it;     // populate the map    verticalSumUtil(root, 0, Map);     // Prints the values stored by VerticalSumUtil()    for (it = Map.begin(); it != Map.end(); ++it)    {        cout << it->first << ": "             << it->second << endl;    }} // Driver program to test above functionsint main(){    // Create binary tree as shown in above figure    Node *root = newNode(1);    root->left = newNode(2);    root->right = newNode(3);    root->left->left = newNode(4);    root->left->right = newNode(5);    root->right->left = newNode(6);    root->right->right = newNode(7);    root->right->left->right = newNode(8);    root->right->right->right = newNode(9);     cout << "Following are the values of vertical"            " sums with the positions of the "            "columns with respect to root\n";    verticalSum(root);     return 0;}// This code is contributed by Aditi Sharma
import java.util.TreeMap;  // Class for a tree nodeclass TreeNode {      // data members    private int key;    private TreeNode left;    private TreeNode right;      // Accessor methods    public int key()        { return key; }    public TreeNode left()  { return left; }    public TreeNode right() { return right; }      // Constructor    public TreeNode(int key)   { this.key = key; left = null; right = null; }      // Methods to set left and right subtrees    public void setLeft(TreeNode left)   { this.left = left; }    public void setRight(TreeNode right) { this.right = right; }}  // Class for a Binary Treeclass Tree {      private TreeNode root;      // Constructors    public Tree() { root = null; }    public Tree(TreeNode n) { root = n; }      // Method to be called by the consumer classes    // like Main class    public void VerticalSumMain() { VerticalSum(root); }      // A wrapper over VerticalSumUtil()    private void VerticalSum(TreeNode root) {          // base case        if (root == null) { return; }          // Creates an empty TreeMap hM        TreeMap<Integer, Integer> hM =                   new TreeMap<Integer, Integer>();          // Calls the VerticalSumUtil() to store the        // vertical sum values in hM        VerticalSumUtil(root, 0, hM);          // Prints the values stored by VerticalSumUtil()        if (hM != null) {            System.out.println(hM.entrySet());        }    }      // Traverses the tree in in-order form and builds    // a hashMap hM that contains the vertical sum    private void VerticalSumUtil(TreeNode root, int hD,                         TreeMap<Integer, Integer> hM) {          // base case        if (root == null) {  return; }          // Store the values in hM for left subtree        VerticalSumUtil(root.left(), hD - 1, hM);          // Update vertical sum for hD of this node        int prevSum = (hM.get(hD) == null) ? 0 : hM.get(hD);        hM.put(hD, prevSum + root.key());          // Store the values in hM for right subtree        VerticalSumUtil(root.right(), hD + 1, hM);    }}  // Driver class to test the verticalSum methodspublic class Main {      public static void main(String[] args) {        /* Create the following Binary Tree              1            /    \          2        3         / \      / \        4   5    6   7          */        TreeNode root = new TreeNode(1);        root.setLeft(new TreeNode(2));        root.setRight(new TreeNode(3));        root.left().setLeft(new TreeNode(4));        root.left().setRight(new TreeNode(5));        root.right().setLeft(new TreeNode(6));        root.right().setRight(new TreeNode(7));        Tree t = new Tree(root);          System.out.println("Following are the values of" +                           " vertical sums with the positions" +                        " of the columns with respect to root ");        t.VerticalSumMain();    }}
# Python3 program to find Vertical Sum in# a given Binary Tree # Node definitionclass newNode:         def __init__(self, data):                 self.left = None        self.right = None        self.data = data         # Traverses the tree in in-order form and# populates a hashMap that contains the# vertical sumdef verticalSumUtil(root, hd, Map):     # Base case    if(root == None):        return         # Recur for left subtree    verticalSumUtil(root.left, hd - 1, Map)     # Add val of current node to    # map entry of corresponding hd    if(hd in Map.keys()):        Map[hd] = Map[hd] + root.data    else:        Map[hd] = root.data             # Recur for right subtree    verticalSumUtil(root.right, hd + 1, Map)     # Function to find vertical_sumdef verticalSum(root):     # a dictionary to store sum of    # nodes for each horizontal distance    Map = {}         # Populate the dictionary    verticalSumUtil(root, 0, Map);     # Prints the values stored    # by VerticalSumUtil()    for i,j in Map.items():        print(i, "=", j, end = ", ")     # Driver Codeif __name__ == "__main__":         '''      Create the following Binary Tree              1            /    \          2        3         / \      / \        4   5    6   7    '''    root = newNode(1)    root.left = newNode(2)    root.right = newNode(3)    root.left.left = newNode(4)    root.left.right = newNode(5)    root.right.left = newNode(6)    root.right.right = newNode(7)         print("Following are the values of vertical "          "sums with the positions of the "          "columns with respect to root")         verticalSum(root)     # This code is contributed by vipinyadav15799
// C# program to find Vertical Sum in// a given Binary Treeusing System;using System.Collections.Generic; // Class for a tree nodeclass TreeNode{     // data members    public int key;    public TreeNode left;    public TreeNode right;     // Accessor methods    public int Key()    {        return key;    }    public TreeNode Left() { return left; }    public TreeNode Right() { return right; }     // Constructor    public TreeNode(int key)    {        this.key = key;        left = null;        right = null;    }     // Methods to set left and right subtrees    public void setLeft(TreeNode left)    {        this.left = left;    }    public void setRight(TreeNode right)    {        this.right = right;    }} // Class for a Binary Treeclass Tree{    private TreeNode root;     // Constructors    public Tree() { root = null; }    public Tree(TreeNode n) { root = n; }     // Method to be called by the consumer classes    // like Main class    public void VerticalSumMain()    {        VerticalSum(root);    }     // A wrapper over VerticalSumUtil()    private void VerticalSum(TreeNode root)    {         // base case        if (root == null) { return; }         // Creates an empty hashMap hM        Dictionary<int,                   int> hM = new Dictionary<int,                                            int>();         // Calls the VerticalSumUtil() to store the        // vertical sum values in hM        VerticalSumUtil(root, 0, hM);         // Prints the values stored by VerticalSumUtil()        if (hM != null)        {            Console.Write("[");            foreach(KeyValuePair<int, int> entry in hM)            {                Console.Write(entry.Key + " = " +                              entry.Value + ", ");            }            Console.Write("]");        }    }     // Traverses the tree in in-order form and builds    // a hashMap hM that contains the vertical sum    private void VerticalSumUtil(TreeNode root, int hD,                                 Dictionary<int, int> hM)    {         // base case        if (root == null) { return; }         // Store the values in hM for left subtree        VerticalSumUtil(root.Left(), hD - 1, hM);         // Update vertical sum for hD of this node        int prevSum = 0;        if(hM.ContainsKey(hD))        {            prevSum = hM[hD];            hM[hD] = prevSum + root.Key();        }        else            hM.Add(hD, prevSum + root.Key());         // Store the values in hM for right subtree        VerticalSumUtil(root.Right(), hD + 1, hM);    }} // Driver Codepublic class GFG{    public static void Main(String[] args)    {        /* Create the following Binary Tree            1            / \        2     3        / \     / \        4 5 6 7         */        TreeNode root = new TreeNode(1);        root.setLeft(new TreeNode(2));        root.setRight(new TreeNode(3));        root.Left().setLeft(new TreeNode(4));        root.Left().setRight(new TreeNode(5));        root.Right().setLeft(new TreeNode(6));        root.Right().setRight(new TreeNode(7));        Tree t = new Tree(root);         Console.WriteLine("Following are the values of" +                          " vertical sums with the positions" +                          " of the columns with respect to root ");        t.VerticalSumMain();    }} // This code is contributed by Rajput-Ji
<script>// JavaScript program to find Vertical Sum in// a given Binary Tree // Node definitionclass newNode{   constructor(data){    this.left = null        this.right = null        this.data = data  }     }         // Traverses the tree in in-order form and// populates a hashMap that contains the// vertical sumfunction verticalSumUtil(root, hd, map){        // Base case    if(root == null)    return; // Recur for left subtree  verticalSumUtil(root.left, hd - 1, map) // Add val of current node to// map entry of corresponding hd   if(map.has(hd) == true)     map.set(hd , map.get(hd) + root.data)   else     map.set(hd , root.data)   // Recur for right subtree   verticalSumUtil(root.right, hd + 1, map) } // Function to find vertical_sumfunction verticalSum(root){ // a dictionary to store sum of// nodes for each horizontal distance  let map = new Map() // Populate the dictionary  verticalSumUtil(root, 0, map); // Prints the values stored// by VerticalSumUtil()  for(const [i,j] of map.entries())     document.write(i + ": " + j) }     // Driver Code             //  Create the following Binary Tree        //     1        //     / \        // 2     3        /// \     / \    // 4   5 6 7         root = new newNode(1)    root.left = new newNode(2)    root.right = new newNode(3)    root.left.left = new newNode(4)    root.left.right = new newNode(5)    root.right.left = new newNode(6)    root.right.right = new newNode(7)  root.right.left.right = new newNode(8);  root.right.right.right = new newNode(9);         document.write("Following are the values of vertical sums with the positions of the columns with respect to root")         verticalSum(root)     // This code is contributed by shinjanpatra</script>
Following are the values of vertical sums with the positions of the columns with respect to root
-2: 4
-1: 2
0: 12
1: 11
2: 7
3: 9
Vertical Sum in Binary Tree | Set 2 (Space Optimized)Time Complexity: O(nlogn)Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
Shivam.Pradhan
Rajput-Ji
vipinyadav15799
maulikgandhi9
kalrap615
shinjanpatra
Amazon
Hash
Tree
Amazon
Hash
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Count pairs with given sum
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
AVL Tree | Set 1 (Insertion)
Level Order Binary Tree Traversal
Binary Tree | Set 3 (Types of Binary Tree)