Vertical Sum in Binary Tree | Set 2 (Space Optimized)

Given a Binary Tree, find vertical sum of the nodes that are in 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

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

We have discussed Hashing Based Solution in Set 1. Hashing based solution requires a Hash Table to be maintained. We know that hashing requires more space than the number of entries in it. In this post, Doubly Linked List based solution is discussed. The solution discussed here requires only n nodes of linked list where n is total number of vertical lines in binary tree. Below is algorithm.

verticalSumDLL(root)
1)  Create a node of doubly linked list node
with value 0. Let the node be llnode.
2)  verticalSumDLL(root, llnode)

verticalSumDLL(tnode, llnode)
1) Add current node's data to its vertical line
llnode.data = llnode.data + tnode.data;
2) Recursively process left subtree
// If left child is not empty
if (tnode.left != null)
{
if (llnode.prev == null)
{
llnode.prev = new LLNode(0);
llnode.prev.next = llnode;
}
verticalSumDLLUtil(tnode.left, llnode.prev);
}
3)  Recursively process right subtree
if (tnode.right != null)
{
if (llnode.next == null)
{
llnode.next = new LLNode(0);
llnode.next.prev = llnode;
}
verticalSumDLLUtil(tnode.right, llnode.next);
}

C++

 /// C++ program of space optimized solution /// to find vertical sum of binary tree. #include    using namespace std;    /// Tree node structure struct TNode{     int key;     struct TNode *left, *right; };    /// Function to create new tree node TNode* newTNode(int key) {     TNode* temp = new TNode;     temp->key = key;     temp->left = temp->right = NULL;     return temp; }    /// Doubly linked list structure struct LLNode{     int key;     struct LLNode *prev, *next; };    /// Function to create new Linked List Node LLNode* newLLNode(int key) {     LLNode* temp = new LLNode;     temp->key = key;     temp->prev = temp->next = NULL;     return temp; }    /// Function that creates Linked list and store /// vertical sum in it. void verticalSumDLLUtil(TNode *root, LLNode *sumNode) {     /// Update sum of current line by adding value     /// of current tree node.     sumNode->key = sumNode->key + root->key;        /// Recursive call to left subtree.     if(root->left)     {         if(sumNode->prev == NULL)         {             sumNode->prev = newLLNode(0);             sumNode->prev->next = sumNode;         }         verticalSumDLLUtil(root->left, sumNode->prev);     }        /// Recursive call to right subtree.     if(root->right)     {         if(sumNode->next == NULL)         {             sumNode->next = newLLNode(0);             sumNode->next->prev = sumNode;         }         verticalSumDLLUtil(root->right, sumNode->next);     } }    /// Function to print vertical sum of Tree. /// It uses verticalSumDLLUtil() to calculate sum. void verticalSumDLL(TNode* root) {     /// Create Linked list node for     /// line passing through root.     LLNode* sumNode = newLLNode(0);        /// Compute vertical sum of different lines.     verticalSumDLLUtil(root, sumNode);        /// Make doubly linked list pointer point     /// to first node in list.     while(sumNode->prev != NULL){         sumNode = sumNode->prev;     }        /// Print vertical sum of different lines     /// of binary tree.     while(sumNode != NULL){         cout << sumNode->key <<" ";         sumNode = sumNode->next;     } }    int main() {     /*                  1                 / \                /   \               2     3              / \   / \             /   \ /   \            4    5 6    7     */     TNode *root = newTNode(1);     root->left = newTNode(2);     root->right = newTNode(3);     root->left->left = newTNode(4);     root->left->right = newTNode(5);     root->right->left = newTNode(6);     root->right->right = newTNode(7);        cout << "Vertical Sums are\n";     verticalSumDLL(root);     return 0; }    // This code is contributed by Rahul Titare

Java

 // Java implementation of space optimized solution // to find vertical sum.    public class VerticalSumBinaryTree {     // Prints vertical sum of different vertical     // lines in tree. This method mainly uses     // verticalSumDLLUtil().     static void verticalSumDLL(TNode root)     {         // Create a doubly linked list node to         // store sum of lines going through root.         // Vertical sum is initialized as 0.         LLNode llnode = new LLNode(0);            // Compute vertical sum of different lines         verticalSumDLLUtil(root, llnode);            // llnode refers to sum of vertical line         // going through root. Move llnode to the         // leftmost line.         while (llnode.prev != null)             llnode = llnode.prev;            // Prints vertical sum of all lines starting         // from leftmost vertical line         while (llnode != null)         {             System.out.print(llnode.data +" ");             llnode = llnode.next;         }     }        // Constructs linked list     static void verticalSumDLLUtil(TNode tnode,                                    LLNode llnode)     {         // Add current node's data to its vertical line         llnode.data = llnode.data + tnode.data;            // Recursively process left subtree         if (tnode.left != null)         {             if (llnode.prev == null)             {                 llnode.prev = new LLNode(0);                 llnode.prev.next = llnode;             }             verticalSumDLLUtil(tnode.left, llnode.prev);         }            // Process right subtree         if (tnode.right != null)         {             if (llnode.next == null)             {                 llnode.next = new LLNode(0);                 llnode.next.prev = llnode;             }             verticalSumDLLUtil(tnode.right, llnode.next);         }     }        // Driver code     public static void main(String[] args)     {         // Let us construct the tree shown above         TNode root = new TNode(1);         root.left = new TNode(2);         root.right = new TNode(3);         root.left.left = new TNode(4);         root.left.right = new TNode(5);         root.right.left = new TNode(6);         root.right.right = new TNode(7);            System.out.println("Vertical Sums are");         verticalSumDLL(root);     }        // Doubly Linked List Node     static class LLNode     {         int data;         LLNode prev, next;         public LLNode(int d) { data = d; }     }        // Binary Tree Node     static class TNode     {         int data;         TNode left, right;         public TNode(int d) { data = d; }     } }

C#

 // C# implementation of space optimized  // solution to find vertical sum.  using System;    class GFG { // Prints vertical sum of different vertical  // lines in tree. This method mainly uses  // verticalSumDLLUtil().  public static void verticalSumDLL(TNode root) {     // Create a doubly linked list node to      // store sum of lines going through root.      // Vertical sum is initialized as 0.      LLNode llnode = new LLNode(0);        // Compute vertical sum of different lines      verticalSumDLLUtil(root, llnode);        // llnode refers to sum of vertical line      // going through root. Move llnode to the      // leftmost line.      while (llnode.prev != null)     {         llnode = llnode.prev;     }        // Prints vertical sum of all lines      // starting from leftmost vertical line      while (llnode != null)     {         Console.Write(llnode.data + " ");         llnode = llnode.next;     } }    // Constructs linked list  public static void verticalSumDLLUtil(TNode tnode,                                       LLNode llnode) {     // Add current node's data to      // its vertical line      llnode.data = llnode.data + tnode.data;        // Recursively process left subtree      if (tnode.left != null)     {         if (llnode.prev == null)         {             llnode.prev = new LLNode(0);             llnode.prev.next = llnode;         }         verticalSumDLLUtil(tnode.left, llnode.prev);     }        // Process right subtree      if (tnode.right != null)     {         if (llnode.next == null)         {             llnode.next = new LLNode(0);             llnode.next.prev = llnode;         }         verticalSumDLLUtil(tnode.right, llnode.next);     } }    // Doubly Linked List Node  public class LLNode {     public int data;     public LLNode prev, next;     public LLNode(int d)     {         data = d;     } }    // Binary Tree Node  public class TNode {     public int data;     public TNode left, right;     public TNode(int d)     {         data = d;     } }    // Driver code  public static void Main(string[] args) {     // Let us construct the tree shown above      TNode root = new TNode(1);     root.left = new TNode(2);     root.right = new TNode(3);     root.left.left = new TNode(4);     root.left.right = new TNode(5);     root.right.left = new TNode(6);     root.right.right = new TNode(7);        Console.WriteLine("Vertical Sums are");     verticalSumDLL(root); } }    // This code is contributed by Shrikant13

Output :

Vertical Sums are
4 2 12 3 7

My Personal Notes arrow_drop_up

Improved By : nik1996, shrikanth13

Article Tags :
Practice Tags :

13

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.