Open In App

Convert an arbitrary Binary Tree to a tree that holds Children Sum Property

Question: Given an arbitrary binary tree, convert it to a binary tree that holds Children Sum Property. You can only increment data values in any node (You cannot change the structure of the tree and cannot decrement the value of any node). 
For example, the below tree doesn't hold the children sum property, convert it to a tree that holds the property.

             50
           /     \     
         /         \
       7             2
     / \             /\
   /     \          /   \
  3        5      1      30

Algorithm: Traverse the given tree in post order to convert it, i.e., first change left and right children to hold the children sum property then change the parent node. 
Let difference between node’s data and children sum be diff. 

diff = node’s children sum - node’s data  


If diff is 0 then nothing needs to be done. 

If diff > 0 ( node’s data is smaller than node's children sum) increment the node’s data by diff.

If diff < 0 (node’s data is greater than the node's children sum) then increment one child’s data. We can choose to increment either left or right child if they both are not NULL. Let us always first increment the left child. Incrementing a child changes the subtree’s children sum property so we need to change left subtree also. So we recursively increment the left child. If left child is empty then we recursively call increment() for right child.

Let us run the algorithm for the given example. 

First convert the left subtree (increment 7 to 8). 
 

             50
           /     \     
         /         \
       8             2
     / \             /\
   /     \          /   \
  3        5      1      30

Then convert the right subtree (increment 2 to 31)

          50
        /    \     
      /        \
    8            31
   / \           / \
 /     \       /     \
3       5    1       30

Now convert the root, we have to increment left subtree for converting the root. 

          50
        /    \     
      /        \
    19           31
   / \           /  \
 /     \       /      \
14      5     1       30

Please note the last step – we have incremented 8 to 19, and to fix the subtree we have incremented 3 to 14.

Implementation: 

/* C++ Program to convert an arbitrary
binary tree to a tree that hold
children sum property */
#include<bits/stdc++.h> 
using namespace std;

class node 
{ 
    public:
    int data; 
    node* left; 
    node* right; 
    
    /* Constructor that allocates a new node 
    with the given data and NULL left and right 
    pointers. */
    node(int data)
    {
        this->data = data; 
        this->left = NULL; 
        this->right = NULL;
    }
}; 

/* This function is used 
to increment left subtree */
void increment(node* node, int diff); 

/* This function changes a tree 
to hold children sum property */
void convertTree(node* node) 
{ 
    int left_data = 0, right_data = 0, diff; 
    
    /* If tree is empty or it's a leaf  
        node then return true */
    if (node == NULL || (node->left == NULL &&
                        node->right == NULL)) 
        return; 
    else
    { 
        /* convert left and right subtrees */
        convertTree(node->left); 
        convertTree(node->right); 
    
        /* If left child is not present then 0 is used 
        as data of left child */
        if (node->left != NULL) 
        left_data = node->left->data; 
    
        /* If right child is not present then 0 is used 
        as data of right child */
        if (node->right != NULL) 
        right_data = node->right->data; 
    
        /* get the diff of node's data and children sum */
        diff = left_data + right_data - node->data; 
    
        /* If node's children sum is 
        greater than the node's data */
        if (diff > 0) 
        node->data = node->data + diff; 
    
        /* THIS IS TRICKY --> If node's data
        is greater than children sum, 
        then increment subtree by diff */
        if (diff < 0) 
        increment(node, -diff); // -diff is used to make diff positive 
    } 
} 

/* This function is used 
to increment subtree by diff */
void increment(node* node, int diff) 
{ 
    /* IF left child is not 
    NULL then increment it */
    if(node->left != NULL) 
    { 
        node->left->data = node->left->data + diff; 
    
        // Recursively call to fix 
        // the descendants of node->left 
        increment(node->left, diff); 
    } 
    else if (node->right != NULL) // Else increment right child 
    { 
        node->right->data = node->right->data + diff; 
    
        // Recursively call to fix 
        // the descendants of node->right 
        increment(node->right, diff); 
    } 
} 

/* Given a binary tree, 
printInorder() prints out its 
inorder traversal*/
void printInorder(node* node) 
{ 
    if (node == NULL) 
        return; 
    
    /* first recur on left child */
    printInorder(node->left); 
    
    /* then print the data of node */
    cout<<node->data<<" ";
    
    /* now recur on right child */
    printInorder(node->right); 
} 

/* Driver code */
int main() 
{ 
    node *root = new node(50); 
    root->left = new node(7); 
    root->right = new node(2); 
    root->left->left = new node(3); 
    root->left->right = new node(5); 
    root->right->left = new node(1); 
    root->right->right = new node(30); 
    
    cout << "\nInorder traversal before conversion: " << endl; 
    printInorder(root);
    
    convertTree(root); 
    
    cout << "\nInorder traversal after conversion: " << endl; 
    printInorder(root); 
    return 0; 
} 

// This code is contributed by rathbhupendra
class Node {
    int data;
    Node left;
    Node right;

    Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class Solution {
    // Function to convert the binary tree to the Children Sum Property
    public void convertToChildrenSumProperty(Node root) {
        convertToChildrenSumPropertyUtil(root);
    }

    // Recursive helper function to convert the binary tree
    private int convertToChildrenSumPropertyUtil(Node root) {
        // Base case: if the current node is null, return 0
        if (root == null) return 0;

        // Recursively convert the left and right subtrees
        int leftSum = convertToChildrenSumPropertyUtil(root.left);
        int rightSum = convertToChildrenSumPropertyUtil(root.right);

        // Calculate the current sum of the children
        int currentSum = leftSum + rightSum;

        // Calculate the difference between the current node's data and the sum of its children
        int difference = currentSum - root.data;

        // If the difference is positive, increment the current node's data
        if (difference > 0) {
            root.data += difference;
        }
        // If the difference is negative, decrement the left or right child's data
        else if (root.left != null) {
            root.left.data -= difference;
            convertToChildrenSumPropertyUtil(root.left);
        } else if (root.right != null) {
            root.right.data -= difference;
            convertToChildrenSumPropertyUtil(root.right);
        }

        // Return the updated data of the current node
        return root.data;
    }

    // Function to perform an inorder traversal of the binary tree
    public void inorderTraversal(Node root) {
        if (root == null) return;
        inorderTraversal(root.left);
        System.out.print(root.data + " ");
        inorderTraversal(root.right);
    }

    public static void main(String[] args) {
        // Create the example binary tree
        Node root = new Node(50);
        root.left = new Node(7);
        root.right = new Node(2);
        root.left.left = new Node(3);
        root.left.right = new Node(5);
        root.right.left = new Node(1);
        root.right.right = new Node(30);

        Solution solution = new Solution();
        System.out.println("Inorder traversal before conversion:");
        solution.inorderTraversal(root);
        System.out.println();
        System.out.println();

        solution.convertToChildrenSumProperty(root);

        System.out.println("Inorder traversal after conversion:");
        solution.inorderTraversal(root);
        System.out.println();
    }
}
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def convert_to_children_sum_property(root):
    """
    Wrapper function to convert the entire binary tree to the Children Sum Property.
    """
    convert_to_children_sum_property_util(root)

def convert_to_children_sum_property_util(root):
    """
    Recursive function to convert the binary tree to the Children Sum Property.
    """
    if not root:
        return 0

    # Recursively convert the left and right subtrees
    left_sum = convert_to_children_sum_property_util(root.left)
    right_sum = convert_to_children_sum_property_util(root.right)

    # Calculate the current sum of the children
    current_sum = left_sum + right_sum

    # Calculate the difference between the current node's data and the sum of its children
    difference = current_sum - root.data

    # If the difference is positive, increment the current node's data
    if difference > 0:
        root.data += difference
    # If the difference is negative, decrement the left or right child's data
    elif root.left:
        root.left.data -= difference
        convert_to_children_sum_property_util(root.left)
    elif root.right:
        root.right.data -= difference
        convert_to_children_sum_property_util(root.right)

    # Return the updated data of the current node
    return root.data

def inorder_traversal(root):
    """
    Function to perform an inorder traversal of the binary tree.
    """
    if not root:
        return
    inorder_traversal(root.left)
    print(root.data, end=" ")
    inorder_traversal(root.right)

if __name__ == "__main__":
    # Create the example binary tree
    root = Node(50)
    root.left = Node(7)
    root.right = Node(2)
    root.left.left = Node(3)
    root.left.right = Node(5)
    root.right.left = Node(1)
    root.right.right = Node(30)

    print("Inorder traversal before conversion:")
    inorder_traversal(root)
    print()
    print()

    convert_to_children_sum_property(root)

    print("Inorder traversal after conversion:")
    inorder_traversal(root)
    print()
using System;

public class Node
{
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = null;
        right = null;
    }
}

public class Solution
{
    // Function to convert the binary tree to the Children Sum Property
    public void ConvertToChildrenSumProperty(Node root)
    {
        ConvertToChildrenSumPropertyUtil(root);
    }

    // Recursive helper function to convert the binary tree
    private int ConvertToChildrenSumPropertyUtil(Node root)
    {
        // Base case: if the current node is null, return 0
        if (root == null) return 0;

        // Recursively convert the left and right subtrees
        int leftSum = ConvertToChildrenSumPropertyUtil(root.left);
        int rightSum = ConvertToChildrenSumPropertyUtil(root.right);

        // Calculate the current sum of the children
        int currentSum = leftSum + rightSum;

        // Calculate the difference between the current node's data and the sum of its children
        int difference = currentSum - root.data;

        // If the difference is positive, increment the current node's data
        if (difference > 0)
        {
            root.data += difference;
        }
        // If the difference is negative, decrement the left or right child's data
        else if (root.left != null)
        {
            root.left.data -= difference;
            ConvertToChildrenSumPropertyUtil(root.left);
        }
        else if (root.right != null)
        {
            root.right.data -= difference;
            ConvertToChildrenSumPropertyUtil(root.right);
        }

        // Return the updated data of the current node
        return root.data;
    }

    // Function to perform an inorder traversal of the binary tree
    public void InorderTraversal(Node root)
    {
        if (root == null) return;
        InorderTraversal(root.left);
        Console.Write(root.data + " ");
        InorderTraversal(root.right);
    }

    public static void Main(string[] args)
    {
        // Create the example binary tree
        Node root = new Node(50);
        root.left = new Node(7);
        root.right = new Node(2);
        root.left.left = new Node(3);
        root.left.right = new Node(5);
        root.right.left = new Node(1);
        root.right.right = new Node(30);

        Solution solution = new Solution();
        Console.WriteLine("Inorder traversal before conversion:");
        solution.InorderTraversal(root);
        Console.WriteLine();
        Console.WriteLine();

        solution.ConvertToChildrenSumProperty(root);

        Console.WriteLine("Inorder traversal after conversion:");
        solution.InorderTraversal(root);
        Console.WriteLine();
    }
}
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Recursive function to convert the binary tree to the Children Sum Property
function convertToChildrenSumPropertyUtil(root) {
    // Base case: if the current node is null, return 0
    if (!root) return 0;

    // Recursively convert the left and right subtrees
    let leftSum = convertToChildrenSumPropertyUtil(root.left);
    let rightSum = convertToChildrenSumPropertyUtil(root.right);

    // Calculate the current sum of the children
    let currentSum = leftSum + rightSum;

    // Calculate the difference between the current node's data and the sum of its children
    let difference = currentSum - root.data;

    // If the difference is positive, increment the current node's data
    if (difference > 0) {
        root.data += difference;
    }
    // If the difference is negative, decrement the left or right child's data
    else if (root.left) {
        root.left.data -= difference;
        convertToChildrenSumPropertyUtil(root.left);
    } else if (root.right) {
        root.right.data -= difference;
        convertToChildrenSumPropertyUtil(root.right);
    }

    // Return the updated data of the current node
    return root.data;
}

// Wrapper function to convert the entire binary tree to the Children Sum Property
function convertToChildrenSumProperty(root) {
    convertToChildrenSumPropertyUtil(root);
}

// Function to perform an inorder traversal of the binary tree
function inorderTraversal(root) {
    if (!root) return;
    inorderTraversal(root.left);
    console.log(root.data, " ");
    inorderTraversal(root.right);
}

// Create the example binary tree
let root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);

console.log("Inorder traversal before conversion:");
inorderTraversal(root);
console.log();
console.log();

convertToChildrenSumProperty(root);

console.log("Inorder traversal after conversion:");
inorderTraversal(root);
console.log();

Output
Inorder traversal before conversion: 
3 7 5 50 1 2 30 
Inorder traversal after conversion: 
14 19 5 50 1 31 30 






Time Complexity: O(n^2), Worst case complexity is for a skewed tree such that nodes are in decreasing order from root to leaf.

Space Complexity: O(h) where h is the height of the binary tree.

Please write comments if you find any bug in the above algorithm or a better way to solve the same problem.

METHOD-2: Most Optimized Solution: (Linear Time)

The idea is to fix the children in top-down fashion of Tree,
and fix the children sum property in bottom-up fashion of Tree


Algorithm:

             50
         /        \     
       /           \
     7              2
   / \               /\
 /     \          /    \
3       5      1      30

Here, the issue is having shortage while summing, eg - 1+30 =31 then 3+5 = 8 => 31+8 =39, but u cannot decrement 50 to 39 as per rule.

So while going down the tree increase the value so to make sure we don't end up with shortage.

Then all we need to do is, while returning, just sum the children and replace the parent node.

At last, the Children sum property holds TRUE. (As there is no restriction on the value needs to be minimum as such)

CODE:

#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;
    Node(int val) : data(val), left(nullptr), right(nullptr) {}
};

int convertToChildrenSumProperty(Node* root, int& difference) {
    if (!root) return 0;

    int leftSum = convertToChildrenSumProperty(root->left, difference);
    int rightSum = convertToChildrenSumProperty(root->right, difference);

    int currentSum = leftSum + rightSum;
    difference = currentSum - root->data;

    if (difference > 0) {
        root->data += difference;
    } else if (root->left) {
        root->left->data -= difference;
        convertToChildrenSumProperty(root->left, difference);
    } else if (root->right) {
        root->right->data -= difference;
        convertToChildrenSumProperty(root->right, difference);
    }

    return root->data;
}

void convertToChildrenSumTree(Node* root) {
    int difference = 0;
    convertToChildrenSumProperty(root, difference);
}

void inorderTraversal(Node* root) {
    if (!root) return;
    inorderTraversal(root->left);
    cout << root->data << " ";
    inorderTraversal(root->right);
}

int main() {
    // Create the example binary tree
    Node* root = new Node(50);
    root->left = new Node(7);
    root->right = new Node(2);
    root->left->left = new Node(3);
    root->left->right = new Node(5);
    root->right->left = new Node(1);
    root->right->right = new Node(30);

    cout << "Inorder traversal before conversion: " << endl;
    inorderTraversal(root);
    cout << endl << endl;

    convertToChildrenSumTree(root);

    cout << "Inorder traversal after conversion: " << endl;
    inorderTraversal(root);
    cout << endl;

    return 0;
}
// Java code for the above approach
import java.io.*;

// Java code to convert a given binary tree to
// a tree where every node contains sum of all nodes
// in left and right subtree in the original tree
class Node {
    int data;
    Node left, right;

    Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}

class BinaryTree {
    Node root;

    // method to print the inorder traversal of
    // the binary tree
    void printInorder(Node node)
    {
        if (node == null)
            return;

        /* first recur on left child */
        printInorder(node.left);

        /* then print the data of node */
        System.out.print(node.data + " ");

        /* now recur on right child */
        printInorder(node.right);
    }

    // method to convert the binary tree
    void convertTree(Node root)
    {
        if (root == null)
            return;

        int childSum = 0;

        // sum of children's data
        if (root.left != null)
            childSum += root.left.data;
        if (root.right != null)
            childSum += root.right.data;

        // if children sum is greater than root
        if (childSum >= root.data) {
            root.data = childSum;
        }
        else {
            // if children sum is less than root
            // change both children
            if (root.left != null)
                root.left.data = root.data;
            if (root.right != null)
                root.right.data = root.data;
        }

        // now go down the tree and check others - Inorder
        convertTree(root.left);
        convertTree(root.right);

        // here is the backtracking part happens, as changes
        // may happen
        int totVal = 0;

        if (root.left != null)
            totVal += root.left.data;
        if (root.right != null)
            totVal += root.right.data;

        // Leaf node dont update, as it will make it 0
        if (root.left != null || root.right != null)
            root.data = totVal;
        // So that at last the children Sum property stays
        // TRUE
    }

    /* Driver code */
    public static void main(String[] args)
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(50);
        tree.root.left = new Node(7);
        tree.root.right = new Node(2);
        tree.root.left.left = new Node(3);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(1);
        tree.root.right.right = new Node(30);

        System.out.print(
            "Inorder traversal before conversion: ");
        tree.printInorder(tree.root);

        tree.convertTree(tree.root);

        System.out.print(
            "\nInorder traversal after conversion: ");
        tree.printInorder(tree.root);
    }
}

// This code is contributed by lokeshpotta20.
#Python code for the above approach
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

def printInorder(node):
    if node is None:
        return
    # first recur on left child
    printInorder(node.left)
    # then print the data of node
    print(node.data, end=" ")
    # now recur on right child
    printInorder(node.right)

def convertTree(root):
    if root is None:
        return
    childSum = 0
    if root.left:
        childSum += root.left.data
    if root.right:
        childSum += root.right.data
    if childSum >= root.data:
        # change root
        root.data = childSum
    else:
        # change both children
        if root.left:
            root.left.data = root.data
        if root.right:
            root.right.data = root.data
    # now go down the tree and check others - Inorder
    convertTree(root.left)
    convertTree(root.right)
    # here is the backtracking part happens, as changes may happen
    totVal = 0
    if root.left:
        totVal += root.left.data
    if root.right:
        totVal += root.right.data
    # Leaf node dont update, as it will make it 0
    if root.left or root.right:
        root.data = totVal
    # So that at last the children Sum property stays TRUE

# Driver code
if __name__ == "__main__":
    root = Node(50)
    root.left = Node(7)
    root.right = Node(2)
    root.left.left = Node(3)
    root.left.right = Node(5)
    root.right.left = Node(1)
    root.right.right = Node(30)
    print("Inorder traversal before conversion: ")
    printInorder(root)
    convertTree(root)
    print("\nInorder traversal after conversion: ")
    printInorder(root)
// C# program to convert an arbitrary
// binary tree to a tree that holds
// children sum property
using System;
 
// A binary tree node
public class node{
    public int data;
    public node left, right;
 
    public node(int item){
        data = item;
        left = right = null;
    }
}
 
class GFG{
    public node root;
 
    /* This function changes a tree to
    hold children sum property */
    public virtual void convertTree(node root){
        if(root == null) return;
        
        int childSum = 0;
        
        if(root.left != null) childSum += root.left.data;
        if(root.right != null) childSum += root.right.data;
        
        if(childSum >= root.data){
            // change root
            root.data = childSum;
        }else{
            // change both children
            if(root.left != null) root.left.data = root.data;
            if(root.right != null) root.right.data = root.data;
        }
        
        // now go down the tree and check others - Inorder
        convertTree(root.left);
        convertTree(root.right);
        
        // here is the backtracking part happens, as changes may happend
        int totVal = 0;
        
        if(root.left != null) totVal += root.left.data;
        if(root.right != null) totVal += root.right.data;
        
        // Leaf node don't update, as it will make it 0
        if(root.left != null || root.right != null) root.data = totVal;
        // so that at last the children sum property syas true
    }
 
    public virtual void printInorder(node node){
        if (node == null) return;
     
        /* first recur on left child */
        printInorder(node.left);
     
        /* then print the data of node */
        Console.Write(node.data + " ");
     
        /* now recur on right child */
        printInorder(node.right);
    }
 
    // Driver Code
    public static void Main(string[] args){
        GFG tree = new GFG();
        tree.root = new node(50);
        tree.root.left = new node(7);
        tree.root.right = new node(2);
        tree.root.left.left = new node(3);
        tree.root.left.right = new node(5);
        tree.root.right.left = new node(1);
        tree.root.right.right = new node(30);
     
        Console.WriteLine("Inorder traversal before conversion is :");
        tree.printInorder(tree.root);
     
        tree.convertTree(tree.root);
        Console.WriteLine("");
     
        Console.WriteLine("Inorder traversal after conversion is :");
        tree.printInorder(tree.root);
    }
}
// THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL(KIRTIAGARWAL23121999)
// JavaScript program for the above approach
class node{
    constructor(data){
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

// function to print inorder traversal of binary tree
function printInorder(node)
{
    if(node == null) return;
    
    // first recur on left child
    printInorder(node.left);
    
    // then print the data of node
    console.log(node.data + " ");
    
    // now recur on right child
    printInorder(node.right);
}

function convertTree(root){
    if(root == null) return null;
    
    let childSum = 0;
    if(root.left != null) childSum += root.left.data;
    if(root.right != null) childSum += root.right.data;
    
    if(childSum >= root.data){
        // change root
        root.data = childSum;
    }else{
        // change both children
        if(root.left) root.left.data = root.data;
        if(root.right) root.right.data = root.data;
    }
    
    // now go down the tree and check others - Inorder
    convertTree(root.left);
    convertTree(root.right);
    
    // here is the backtracking part happens, as changes may happen
    let totVal = 0;
    
    if(root.left) totVal += root.left.data;
    if(root.right)  totVal += root.right.data;
    
    // Leaf node dont update, as it will make it 0
    if(root.left || root.right) root.data = totVal;
    //So that at last the children Sum property stays TRUE
}

// driver code to test above function
let root = new node(50);
root.left = new node(7);
root.right = new node(2);
root.left.left = new node(3);
root.left.right = new node(5);
root.right.left = new node(1);
root.right.right = new node(30);

console.log("Inorder Traversal before conversion: ");
printInorder(root);

convertTree(root);

console.log("Inorder Traversal after conversion: ");
printInorder(root);

// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)

Output
Inorder traversal before conversion: 
3 7 5 50 1 2 30 
Inorder traversal after conversion: 
50 100 50 200 50 100 50 






Time Complexity: O(n) as we are doing traversal of the tree only once.

Reason : 

Recurrence Relation :  T(n) = 2*T(n/2) + O(1)
 

Space Complexity: O(ht of tree) best and avg: O(log n ) worst: O(n) Skewed trees.

Reason:

Function call stack of recursion.

Approach using DP:

In this implementation, a queue is used to perform a level-order traversal of the tree. The queue helps to process each node and its children in a breadth-first manner. The program calculates the difference between the sum of the left and right child values and the current node's value. If the difference is positive, the current node's value is increased by the difference. If the difference is negative, the program distributes the difference to the left or right child, depending on which child is present.

Here's the implementation of the given program using a dynamic programming (DP) approach:

#include <iostream>
#include <queue>
using namespace std;

class node 
{
public:
    int data; 
    node* left; 
    node* right;
    
    node(int data)
    {
        this->data = data; 
        this->left = NULL; 
        this->right = NULL;
    }
};

void convertTree(node* root)
{
    if (root == NULL || (root->left == NULL && root->right == NULL))
        return;

    queue<node*> q;
    q.push(root);

    while (!q.empty())
    {
        node* current = q.front();
        q.pop();

        int left_data = 0, right_data = 0;

        if (current->left != NULL)
        {
            q.push(current->left);
            left_data = current->left->data;
        }

        if (current->right != NULL)
        {
            q.push(current->right);
            right_data = current->right->data;
        }

        int diff = left_data + right_data - current->data;

        if (diff > 0)
            current->data += diff;

        if (diff < 0)
        {
            if (current->left != NULL)
                current->left->data += -diff;
            else if (current->right != NULL)
                current->right->data += -diff;
        }
    }
}

void printInorder(node* root)
{
    if (root == NULL)
        return;

    printInorder(root->left);
    cout << root->data << " ";
    printInorder(root->right);
}

int main() 
{
    node *root = new node(50); 
    root->left = new node(7); 
    root->right = new node(2); 
    root->left->left = new node(3); 
    root->left->right = new node(5); 
    root->right->left = new node(1); 
    root->right->right = new node(30); 

    cout << "Inorder traversal before conversion: ";
    printInorder(root);
    cout << endl;

    convertTree(root); 

    cout << "Inorder traversal after conversion: ";
    printInorder(root); 
    cout << endl;

    return 0; 
}
import java.util.LinkedList;
import java.util.Queue;

class Node {
    int data;
    Node left;
    Node right;

    public Node(int data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

public class BinaryTreeConversion {
    public static void convertTree(Node root) {
        if (root == null || (root.left == null && root.right == null))
            return;

        Queue<Node> queue = new LinkedList<>();
        queue.add(root);

        while (!queue.isEmpty()) {
            Node current = queue.poll();

            int leftData = 0, rightData = 0;

            if (current.left != null) {
                queue.add(current.left);
                leftData = current.left.data;
            }

            if (current.right != null) {
                queue.add(current.right);
                rightData = current.right.data;
            }

            int diff = leftData + rightData - current.data;

            if (diff > 0)
                current.data += diff;

            if (diff < 0) {
                if (current.left != null)
                    current.left.data += -diff;
                else if (current.right != null)
                    current.right.data += -diff;
            }
        }
    }

    public static void printInorder(Node root) {
        if (root == null)
            return;

        printInorder(root.left);
        System.out.print(root.data + " ");
        printInorder(root.right);
    }

    public static void main(String[] args) {
        Node root = new Node(50);
        root.left = new Node(7);
        root.right = new Node(2);
        root.left.left = new Node(3);
        root.left.right = new Node(5);
        root.right.left = new Node(1);
        root.right.right = new Node(30);

        System.out.print("Inorder traversal before conversion: ");
        printInorder(root);
        System.out.println();

        convertTree(root);

        System.out.print("Inorder traversal after conversion: ");
        printInorder(root);
        System.out.println();
    }
}
from queue import Queue

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

def convert_tree(root):
    # Base case: If the tree is empty or has only one node, return.
    if root is None or (root.left is None and root.right is None):
        return

    q = Queue()
    q.put(root)

    while not q.empty():
        current = q.get()

        # Initialize variables to store the data of the left and right children.
        left_data, right_data = 0, 0

        # Check if the left child exists and update left_data.
        if current.left is not None:
            q.put(current.left)
            left_data = current.left.data

        # Check if the right child exists and update right_data.
        if current.right is not None:
            q.put(current.right)
            right_data = current.right.data

        # Calculate the difference between the sum of left and right children's data and the current node's data.
        diff = left_data + right_data - current.data

        # If the difference is positive, add it to the current node's data.
        if diff > 0:
            current.data += diff

        # If the difference is negative, distribute it to the left and/or right children.
        if diff < 0:
            # If the left child exists, add the negative difference to it.
            if current.left is not None:
                current.left.data += -diff
            # If the left child doesn't exist, add the negative difference to the right child.
            elif current.right is not None:
                current.right.data += -diff

def print_inorder(root):
    if root is None:
        return

    # Inorder traversal of the tree (left-root-right).
    print_inorder(root.left)
    print(root.data, end=' ')
    print_inorder(root.right)

if __name__ == "__main__":
    root = Node(50)
    root.left = Node(7)
    root.right = Node(2)
    root.left.left = Node(3)
    root.left.right = Node(5)
    root.right.left = Node(1)
    root.right.right = Node(30)

    print("Inorder traversal before conversion: ", end='')
    print_inorder(root)
    print()

    convert_tree(root)

    print("Inorder traversal after conversion: ", end='')
    print_inorder(root)
    print()  # Add this line to ensure the final output is displayed
using System;
using System.Collections.Generic;

class Node
{
    public int Data { get; set; }
    public Node Left { get; set; }
    public Node Right { get; set; }

    public Node(int data)
    {
        Data = data;
        Left = null;
        Right = null;
    }
}

class Program
{
    // Function to convert the tree as per the given logic
    static void ConvertTree(Node root)
    {
        // If the root is null or a leaf node, no conversion is needed
        if (root == null || (root.Left == null && root.Right == null))
            return;

        // Use a queue for level order traversal
        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);

        // Level order traversal to process each node
        while (q.Count > 0)
        {
            Node current = q.Dequeue();

            int leftData = 0, rightData = 0;

            // Enqueue left child if it exists and update leftData
            if (current.Left != null)
            {
                q.Enqueue(current.Left);
                leftData = current.Left.Data;
            }

            // Enqueue right child if it exists and update rightData
            if (current.Right != null)
            {
                q.Enqueue(current.Right);
                rightData = current.Right.Data;
            }

            // Calculate the difference between the sum of left and 
            // right children and the current node's data
            int diff = leftData + rightData - current.Data;

            // If the difference is positive, update the current node's data
            if (diff > 0)
                current.Data += diff;

            // If the difference is negative, distribute it to left or right child
            if (diff < 0)
            {
                if (current.Left != null)
                    current.Left.Data += -diff;
                else if (current.Right != null)
                    current.Right.Data += -diff;
            }
        }
    }

    // Function to print the inorder traversal of the tree
    static void PrintInorder(Node root)
    {
        if (root == null)
            return;

        PrintInorder(root.Left);
        Console.Write(root.Data + " ");
        PrintInorder(root.Right);
    }

    static void Main()
    {
        // Sample tree creation
        Node root = new Node(50);
        root.Left = new Node(7);
        root.Right = new Node(2);
        root.Left.Left = new Node(3);
        root.Left.Right = new Node(5);
        root.Right.Left = new Node(1);
        root.Right.Right = new Node(30);

        Console.Write("Inorder traversal before conversion: ");
        PrintInorder(root);
        Console.WriteLine();

        // Convert the tree
        ConvertTree(root);

        Console.Write("Inorder traversal after conversion: ");
        PrintInorder(root);
        Console.WriteLine();
    }
}
// JavaScript Code for the above approach
class Node {
  constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
  }
}

// Function to modify the binary tree to satisfy the children sum property
function convertTree(root) {
  if (root === null || (root.left === null && root.right === null))
    return;

  const queue = [root];

  while (queue.length > 0) {
    const current = queue.shift();

    let leftData = 0;
    let rightData = 0;

    // Calculate the sum of left and right child node data, if they exist
    if (current.left !== null) {
      queue.push(current.left);
      leftData = current.left.data;
    }

    if (current.right !== null) {
      queue.push(current.right);
      rightData = current.right.data;
    }

    // Calculate the difference between the sum of children and current node data
    const diff = leftData + rightData - current.data;

    // Update the current node data to satisfy the children sum property
    if (diff > 0)
      current.data += diff;

    // If the current node data is greater than the sum of its children,
    // propagate the difference to its children
    if (diff < 0) {
      if (current.left !== null)
        current.left.data += -diff;
      else if (current.right !== null)
        current.right.data += -diff;
    }
  }
}

// Function to print the inorder traversal of the binary tree
function printInorder(root) {
  if (root === null)
    return;

  printInorder(root.left);
  process.stdout.write(root.data + " ");
  printInorder(root.right);
}

// Create the binary tree
const root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);

console.log("Inorder traversal before conversion:");
printInorder(root);
console.log();

// Modify the binary tree to satisfy the children sum property
convertTree(root);

console.log("Inorder traversal after conversion:");
printInorder(root);
console.log();
// THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL

Output:

Inorder traversal before conversion: 
3 7 5 50 1 2 30 
Inorder traversal after conversion:
 43 48 5 50 1 31 30 

Time Complexity: O(n)

Space Complexity: O(n)


The above Method-2 Idea, Algorithm, and Code are contributed by Balakrishnan R (rbkraj000 - GFG ID).

Article Tags :