Convert an arbitrary Binary Tree to a tree that holds Children Sum Property
Asked by Shekhar
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.
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 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 smaller than the node's children sum) then increment one child’s data. We can choose to increment either left or right child. Let us always increment the left child. Incrementing a child changes the subtree’s children sum property so we need to change left subtree also. Left subtree is fixed by incrementing all the children in left subtree by diff, we have a function increment() for this purpose (see below C code).
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:
/* Program to convert an aribitary binary tree to
a tree that holds children sum property */
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* left;
struct node* right;
};
/* This function is used to increment left subtree */
void increment(struct node* node, int diff);
/* Helper function that allocates a new node
with the given data and NULL left and right
pointers. */
struct node* newNode(int data);
/* This function changes a tree to to hold children sum
property */
void convertTree(struct 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 data is smaller than children sum,
then increment node's data by diff */
if(diff > 0)
node->data = node->data + diff;
/* THIS IS TRICKY --> If node's data is greater than children sum,
then increment left subtree by diff */
if(diff < 0)
increment(node, -diff);
}
}
/* This function is used to increment left subtree */
void increment(struct node* node, int diff)
{
/* This if is for the case where left child is NULL */
if(node->left == NULL)
{
node->left = newNode(diff);
return;
}
/* Go in depth, and fix all left children */
while(node->left != NULL)
{
node->left->data = node->left->data + diff;
node = node->left;
}
}
/* Given a binary tree, printInorder() prints out its
inorder traversal*/
void printInorder(struct node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
printf("%d ", node->data);
/* now recur on right child */
printInorder(node->right);
}
/* Helper function that allocates a new node
with the given data and NULL left and right
pointers. */
struct node* newNode(int data)
{
struct node* node =
(struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/* Driver program to test above functions */
int main()
{
struct node *root = newNode(50);
root->left = newNode(7);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(5);
root->right->left = newNode(1);
root->right->right = newNode(30);
printf("\n Inorder traversal before conversion ");
printInorder(root);
convertTree(root);
printf("\n Inorder traversal after conversion ");
printInorder(root);
getchar();
return 0;
}
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: Based on convention you follow - if size of stack for function calls is considered then O(n), otherwise O(1)
Now extend the above question for an n-ary tree.
Please write comments if you find any bug in the above algorithm or a better way to solve the same problem.


Why not Increment the value of the right node if left node is not present instead of creating the left node…
This algorithm does not take into account if different nodes have same values. Moreover, i don’t think adding a new node to a given tree in order to satisfy the children sum property is practical, instead, in the function convertTree(), increment the right subtree if the left one is NULL.
Yes, i agree.
Could anyone provide an algorithm where the structure of the tree is not changed.
Sorry, Missed the statement “you can only increment data values in any node”. Now its working fine
Thanks
@Jyothi: Please read the question statement carefully. The question says you can only increment data values in any node. So in the 3rd step, we cannot decrement root’s value from 50 to 8 + 31. We are following the convention of incrementing the left subtree in such cases, so we have incremented the left subtree.
Now, the question is – why are we incrementing left subtree not just left child? We are doing this because just incrementing the left child makes left subtree violate children sum property.
The program works for trees with more than two levels. Let us know the tree for which you faced problems.
In the 3rd step why are we changing the left subtree values instead of changing the root node value directly. Instead of summing 8+31 directly why are we changing the values 8->19,3->14.
And why didnt you follow the same steps for 1 and 2. If the tree level is more than 2 how would you proceed?