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 30Here, 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).