Vertical Sum in a given Binary Tree | Set 1

• Difficulty Level : Medium
• Last Updated : 19 Oct, 2021

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 lines
Vertical-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 7
So 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++

 // C++ program to find Vertical Sum in // a given Binary Tree #include using namespace std;    struct Node {     int data;     struct Node *left, *right; };    // A utility function to create a new // Binary Tree node Node* 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 sum void verticalSumUtil(Node *node, int hd,                      map &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 sum void 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 functions int 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

Java

 import java.util.TreeMap;     // Class for a tree node class 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 Tree class 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 hM =                    new TreeMap();             // 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 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 methods public 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

 # Python3 program to find Vertical Sum in  # a given Binary Tree     # Node definition  class 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 sum  def 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_sum  def 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 Code  if __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#

 // C# program to find Vertical Sum in // a given Binary Tree using System; using System.Collections.Generic;    // Class for a tree node class 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 Tree class 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 hM = new Dictionary();            // 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 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 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 Code public 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

Output

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)