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 structure of tree and cannot decrement 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 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:

/* 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 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(struct 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(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.

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





  • danny

    A O(n) solution is possible :-
    Algorithm..
    We take the Top-Bottom approach
    Step-1:- Check the parents value and Sum of child’s value
    take, diff=(parent value-sum of child’s value).
    If diff>0,
    then, arbitrary choose either left and right child and add the diff to the child value.
    Else,
    arbitrary choose either left and right child and subtract the diff to the child value.
    Step-2:- Recursively Call for left and right child.

    Please comment and correct me if I am making some mistake or if my concept is wrong…..

  • Ameet Chhatwal

    A clean O(n) Solution:
    1. Keep adding the root value to its child value and keep traversing down the tree. Note(IMP) if the value is negative make it positive * (-1)
    2. once a node’s right and left child are visited update the node’s value to left child + right child (Trick is nodes value will always increase since you have already added value of root to child)

    Any feedback is appreciated

  • Sumit Poddar

    Kindly check my JAVA implementation for the same. I believe the solution will have O(n) time complexity. Requesting groups to review it and let me know in case of any issues..

    —————————————————————————————

    public class TreeToCSPTree {

    /**
    * @param args
    */
    public static void main(String[] args) {
    Node n1 = new Node(5, new Node(2, null, null), new Node(5, null, null));
    Node n2 = new Node(3, null, null);
    Node n3 = new Node(7, n2, n1);
    Node n4 = new Node(1, null, null);
    Node n5 = new Node(50, n4, new Node(30, null, null));
    Node n = new Node(50, n3, n5);
    Node partn = convert(n, null, new ChangeAttr());
    System.out.println(partn);

    }

    public static Node convert(Node root, Node parent, ChangeAttr chngeAttr) {
    if ((root.left == null) && (root.right == null)) {
    return root;
    }
    Node left = new Node(0), right = new Node(0);
    if (root.left != null) {
    left = convert(root.left, root, chngeAttr);
    }
    if (root.right != null) {
    right = convert(root.right, root, chngeAttr);
    }
    if ((chngeAttr.data > -1) && (chngeAttr.toChange)) {
    if (root.left != null
    && root.left.data < root.left.data + chngeAttr.data) {
    root.left.data = root.left.data + chngeAttr.data;
    left = root.left;
    } else if (root.right != null
    && root.right.data root.data) {
    if (parent == null) {
    root.data = left.data + right.data;
    } else {
    if (parent.left.data == root.data) {
    parent.left.data = left.data + right.data;
    } else {
    parent.right.data = left.data + right.data;
    }
    }
    } else if ((left.data + right.data) < root.data) {
    chngeAttr.data = root.data – (left.data + right.data);
    chngeAttr.toChange = true;
    convert(root, root, chngeAttr);
    }
    return root;
    }
    }

    class ChangeAttr {
    int data = -1;
    boolean toChange = false;

    }

  • vaibhav

    my code if problem arises ill be thankful to critic :)
    #include

    #include

    #include

    using namespace std;

    void add(int);

    typedef struct node { int value;

    struct node *left;

    struct node *right; }mynode;

    int child(mynode*root)

    {if(!root)

    return 0;

    int h1,h2;

    h1=child(root->left);

    h2=child(root->right);

    if(root->value>h1+h2&&h1&&h2)

    {root->right->value=root->value-root->left->value;

    child(root->right);

    return(root->value);

    }

    if(root->value>h1+h2&&!h1&&h2)

    {root->right->value+=root->value-root->right->value;

    child(root->right);

    return(root->value);

    }

    if(root->value>h1+h2&&h1&&!h2)

    {root->left->value=root->value;

    child(root->left);

    return(root->value);

    }

    if(root->valuevalue=h1+h2;

    return(root->value);

    }

    return(root->value);

    }

  • Rohan

    How about this aprroach :

    int makeChildSumTree(struct node* node)

    {

    if(!node) return 0;

    int left = makeChildSumTree(node->left);

    int right = makeChildSumTree(node->right);

    if(node->data data = left + right;

    else{

    if(node->left && node->right){

    node->left->data = node->data – node->right->data;

    makeChildSumTree(node->left);

    }

    else if(node->left){

    node->left->data = node->data;

    makeChildSumTree(node->left);

    }

    else if(node->right){

    node->right->data = node->data;

    makeChildSumTree(node->left);

    }

    }

    return node->data;

    }

  • vinit

    @GeekforGeeks i think there can be O(n) solution possible for this problem. please correct me if u find any mistake.

    Algorithm:-
    step 1. bottom up part( if sum of childs weight >parent weight then give this to parent)more or like post order traversal

    Note:- step 1 will ensure that parents will have value more than or equal to sum of its child.

    step2.top down part (if sum of childs weight >parents weight distribute it to one of the child )

     
    /* Paste your code here (You may delete these lines if not writing code) */
     

    void make_Sum_Tree_Bottomup(struct Bt_Node *root){
    if(root!=NULL){
    make_Sum_Tree_Bottomup(root->left);
    make_Sum_Tree_Bottomup(root->right);
    int l=0;
    int r=0;
    if(root->left!=NULL){
    l=root->left->data;
    }
    if(root->right!=NULL){
    r=root->right->data;
    }
    if(root->left==NULL && root->right==NULL){
    l=root->data;//base case
    }
    if(l+r>root->data){
    root->data=l+r;
    }
    }
    }
    void make_Sum_Tree_TopDown(struct Bt_Node *root){
    if(root!=NULL){
    int l=0;
    int r=0;
    if(root->left!=NULL){
    l=root->left->data;
    }
    if(root->right!=NULL){
    r=root->right->data;
    }
    if(root->left!=NULL){
    if(l+rdata)
    root->left->data=root->data-r;
    }
    else{
    if(l+rdata)
    root->right->data=root->data-l;

    }
    }
    }

    void make_Sum_Tree(struct Bt_Node *root){
    make_Sum_Tree_Bottomup(root);
    make_Sum_Tree_TopDown(root);
    }

  • denial

    @geeksforgeeks :

    Please correct the algorithm above. In condition where ‘diff < 0′ it is written “node’s data is smaller than the node’s children sum” , it should be “node’s children sum is smaller than the node’s data” . Correct if I’m wrong.

    • GeeksforGeeks

      Please take a closer look, it is greater, not smaller.

      “If node’s data is *greater* than children sum,then increment subtree by diff”

      • denial

        @geeksforgeeks :
        I’m talking about algorithm not code.

        ————————————-
        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 ————————————

        • GeeksforGeeks

          @denial: Thanks for pointing this out. We have corrected the line. Appreciate your contribution.

  • 4m7u1

    smart 😀 !

  • abhishek08aug

    C++ code:

     
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
     
    class tree_node {
      private:
        int data;
        tree_node * left;
        tree_node * right;
      public:
        tree_node() {
          left=NULL;
          right=NULL;
        }
        void set_data(int data) {
          this->data=data;
        }
        int get_data() {
          return this->data;
        }
        void set_left(tree_node * left) {
          this->left=left;
        }
        tree_node * get_left() {
          return this->left;
        }
        void set_right(tree_node * right) {
          this->right=right;
        }
        tree_node * get_right() {
          return this->right;
        }
        tree_node ** get_left_ref() {
          return &(this->left);
        }
        tree_node ** get_right_ref() {
          return &(this->right);
        }
    };
     
    class tree {
      private:
        tree_node * root;
        int size;
        void _recursive_insert(tree_node ** root_ref, int value);
        void _print_preorder(tree_node * root);
        void _print_inorder(tree_node * root);
        void _print_postorder(tree_node * root);
        int _find_size(tree_node * root);
        int _are_identical(tree_node * tn1, tree_node * tn2);
        int _find_height(tree_node * root);
        void _delete_tree(tree_node ** root);
        void _mirror(tree_node * root);
        void _print_paths(tree_node * root, int * path_nodes, int next_vacant_position);
        void _print_array(int * array, int len);
        tree_node * _lowest_common_ancestor(tree_node * parent, tree_node * root, int a, int b);
        tree_node * _find_node(tree_node * root, int value);
        tree_node * _min_node(tree_node * root);
        void _print_level_order(tree_node * root);
        int _count_leaf_nodes(tree_node * root);
        int _is_bst(tree_node * root);
        int _children_sum(tree_node * root);
        void _ensure_children_sum(tree_node * root);
      public:
        tree() {
          root=NULL;
          size=0;
        }
        void insert(int value);
        void recursive_insert(int value);
        void print_preorder();
        void print_inorder();
        void print_postorder();
        int find_size();
        int get_size() {
          return this->size;
        }
        int are_identical(tree t);
        int find_height();
        void delete_tree();
        void mirror();
        void print_paths();
        tree_node * lowest_common_ancestor(int a, int b);
        tree_node * find_node(int value);
        tree_node * min_node();
        void print_level_order();
        int count_leaf_nodes();
        int is_bst();
        int children_sum();
        void ensure_children_sum();
    };
     
    void tree::insert(int value) {
      if(root==NULL) {
        root=new tree_node;
        root->set_data(value);
      } else {
        tree_node * parent=NULL;
        tree_node * current=root;
        tree_node * new_node=new tree_node;
        new_node->set_data(value);
        while(current!=NULL) {
          if(value<=current->get_data()) {
            parent=current;
            current=current->get_left();
          } else {
            parent=current;
            current=current->get_right();
          }
        }
        if(value<=parent->get_data() && parent->get_left()==NULL) {
          parent->set_left(new_node);
        } else if(value>parent->get_data() && parent->get_right()==NULL) {
          parent->set_right(new_node);
        }
      }
      size++;
    }
     
    void tree::recursive_insert(int value) {
      _recursive_insert(&root, value);
      size++;
    }
     
    void tree::_recursive_insert(tree_node ** root_ref, int value) {
      if(*root_ref==NULL) {
        tree_node * new_node=new tree_node;
        new_node->set_data(value);
        *root_ref=new_node;   
      } else {
        if(value<=(*root_ref)->get_data()) {
          _recursive_insert((*root_ref)->get_left_ref(), value);
        } else {
          _recursive_insert((*root_ref)->get_right_ref(), value);
        }
      }
    }
     
    void tree::print_preorder() {
      if(root==NULL) {
        return;
      }
      _print_preorder(root);
      cout<<endl;
    }
     
    void tree::_print_preorder(tree_node * root) {
      if(root==NULL) {
        return;
      }
      cout<<root->get_data()<<" ";
      if(root->get_left()!=NULL)
        _print_preorder(root->get_left());
      if(root->get_right()!=NULL)
        _print_preorder(root->get_right());
    }
     
    void tree::print_inorder() {
      if(root==NULL) {
        return;
      }
      _print_inorder(root);
      cout<<endl;
    }
     
    void tree::_print_inorder(tree_node * root) {
      if(root==NULL) {
        return;
      }
      if(root->get_left()!=NULL)
        _print_inorder(root->get_left());
      cout<<root->get_data()<<" ";
      if(root->get_right()!=NULL)
        _print_inorder(root->get_right());
    }
     
    void tree::print_postorder() {
      if(root==NULL) {
        return;
      }
      _print_postorder(root);
      cout<<endl;
    }
     
    void tree::_print_postorder(tree_node * root) {
      if(root==NULL) {
        return;
      }
      if(root->get_left()!=NULL)
        _print_postorder(root->get_left());
      if(root->get_right()!=NULL)
        _print_postorder(root->get_right());
      cout<<root->get_data()<<" ";
    }
    
    int tree::find_size() {
      return _find_size(root);
    }
    
    int tree::_find_size(tree_node * root) {
      if(root==NULL) {
        return 0;
      } else {
        return 1+_find_size(root->get_left())+_find_size(root->get_right());
      }
    }
    
    int tree::are_identical(tree t) {
      return _are_identical(this->root, t.root);
    }
    
    int tree::_are_identical(tree_node * tn1, tree_node * tn2) {
      if(tn1==NULL && tn2==NULL) {
        return 1;
      } else if((tn1==NULL && tn2!=NULL) || (tn1!=NULL && tn2==NULL) || (tn1->get_data()!=tn2->get_data())) {
        return 0;
      } else {
        return _are_identical(tn1->get_left(), tn2->get_left()) && _are_identical(tn1->get_right(), tn2->get_right());
      }
    }
    
    int tree::find_height() {
      return _find_height(root);
    }
    
    int tree::_find_height(tree_node * root) {
      if(root==NULL) {
        return 0;
      }
      else {
        return 1+max(_find_height(root->get_left()), _find_height(root->get_right()));
      }
    }
    
    void tree::delete_tree() {
      _delete_tree(&root);
      size=0;
    }
    
    void tree::_delete_tree(tree_node ** root) {
      if(*root==NULL) {
        return;
      } else {
        if((*root)->get_left()!=NULL) {
          _delete_tree((*root)->get_left_ref());
        }
        if((*root)->get_right()!=NULL) {
          _delete_tree((*root)->get_right_ref());
        }
        delete(*root);
        *root=NULL;
      }
    }
    
    /* alternate _delete_tree */
    /*
    void tree::_delete_tree(tree_node ** root) {
      if(*root==NULL) {
        return;
      } else {
        if((*root)->get_left()!=NULL) {
          tree_node * left_ref=(*root)->get_left();
          _delete_tree(&left_ref);
        }
        if((*root)->get_right()!=NULL) {
          tree_node * right_ref=(*root)->get_right();
          _delete_tree(&right_ref);
        }
        delete(*root);
        *root=NULL;
      }
    }
    */
    
    void tree::mirror() {
      _mirror(root);
    }
    
    void tree::_mirror(tree_node * root) {
      if(root==NULL) {
        return;
      }
    
      tree_node * temp=root->get_left();
      root->set_left(root->get_right());
      root->set_right(temp);
      _mirror(root->get_left());
      _mirror(root->get_right());
    }
    
    void tree::print_paths(){
       int max_path_length=find_height();
       int * path_nodes=(int *)calloc(sizeof(int), max_path_length);
      _print_paths(root, path_nodes, 0);
    }
    
    void tree::_print_paths(tree_node * root, int * path_nodes, int next_vacant_position){
      if(root==NULL) {
        return;
      } else if(root->get_left()==NULL && root->get_right()==NULL) {
        *(path_nodes+next_vacant_position)=root->get_data();
        _print_array(path_nodes, next_vacant_position);
      } else {
        *(path_nodes+next_vacant_position)=root->get_data();
        _print_paths(root->get_left(), path_nodes, next_vacant_position+1);
        _print_paths(root->get_right(), path_nodes, next_vacant_position+1);
      }
    }
    
    void tree::_print_array(int * array, int len) {
      int i;
      for(i=0; i<=len; i++) {
        cout<<*(array+i)<<" ";
      }
      cout<<endl;
    }
    
    tree_node * tree::find_node(int value) {
      return _find_node(root, value);
    }
    
    tree_node * tree::_find_node(tree_node * root, int value) {
      if(root==NULL || root->get_data()==value) {
        return root;
      } else if(value<=root->get_data()) {
        return _find_node(root->get_left(), value);
      } else {
        return _find_node(root->get_right(), value);
      }
    }
    
    tree_node * tree::lowest_common_ancestor(int a, int b) {
      return _lowest_common_ancestor(NULL, root, a, b);
    }
    
    tree_node * tree::_lowest_common_ancestor(tree_node * parent, tree_node * root, int a, int b) {
      if(root==NULL) {
        return root;
      } else if((root->get_data()==a && (root->get_left()->get_data()==b || root->get_right()->get_data()==b))
                 || (root->get_data()==b && (root->get_left()->get_data()==a || root->get_right()->get_data()==a))) {
        return parent;
      } else if((_find_node(root->get_left(), a)!=NULL && _find_node(root->get_right(), b)!=NULL)
            || (_find_node(root->get_left(), b)!=NULL && _find_node(root->get_right(), a)!=NULL)) {
        return root; 
      } else if(_find_node(root->get_left(), a)!=NULL && _find_node(root->get_left(), b)!=NULL) {
        return _lowest_common_ancestor(root, root->get_left(), a, b);
      } else if(_find_node(root->get_right(), a)!=NULL && _find_node(root->get_right(), b)!=NULL) {
        return _lowest_common_ancestor(root, root->get_right(), a, b);
      } else {
        return NULL;
      }
    }
    
    tree_node * tree::min_node() {
      return _min_node(root);
    }
    
    tree_node * tree::_min_node(tree_node * root) {
      if(root==NULL || root->get_left()==NULL) {
        return root;
      } else {
        return _min_node(root->get_left());
      }
    }
    
    int tree::count_leaf_nodes() {
      return _count_leaf_nodes(root);
    }
    
    int tree::_count_leaf_nodes(tree_node * root) {
      if(root==NULL) {
        return 0;
      } else if(root->get_left()==NULL && root->get_right()==NULL) {
        return 1;
      } else {
        return _count_leaf_nodes(root->get_left())+_count_leaf_nodes(root->get_right());
      }
    }
    
    
    int tree::is_bst() {
      return _is_bst(root);
    }
    
    int tree::_is_bst(tree_node * root) {
      static tree_node * previous=NULL;
      if(root==NULL) {
        return 1;
      } else {
        if(!_is_bst(root->get_left())) {
          return 0;
        }
        if(previous!=NULL && (previous->get_data())>(root->get_data())) {
          return 0;
        }
        previous=root;
        if(!_is_bst(root->get_right())) {
          return 0;
        }    
      }
    }
    
    int tree::children_sum() {
      return _children_sum(root);
    }
    
    int tree::_children_sum(tree_node * root) {
      if(root==NULL) {
        return 1;
      }
      if(root->get_left()==NULL && root->get_right()==NULL) {
        return 1;
      }
      else if(_children_sum(root->get_left()) && _children_sum(root->get_right())){
        int left_data;
        int right_data;
        if(root->get_left()!=NULL) {
          left_data=root->get_left()->get_data();
        } else {
          left_data=0;
        }
        if(root->get_right()!=NULL) {
          right_data=root->get_right()->get_data();
        } else {
          right_data=0;
        }
    
        if(left_data+right_data==root->get_data()) {
          return 1;
        } else {
          return 0;
        }
      } else {
        return 0;
      }
    }
    
    void tree::ensure_children_sum() {
      _ensure_children_sum(root);
    }
    
    void tree::_ensure_children_sum(tree_node * root) {
      if(root==NULL || (root->get_left()==NULL && root->get_right()==NULL)) {
        return;
      } else {
        _ensure_children_sum(root->get_left());
        _ensure_children_sum(root->get_right());
        int left_data;
        int right_data;
        if(root->get_left()!=NULL) {
          left_data=root->get_left()->get_data();
        } else {
          left_data=0;
        }
        if(root->get_right()!=NULL) {
          right_data=root->get_right()->get_data();
        } else {
          right_data=0;
        }
        root->set_data(left_data+right_data);
      }
    }
    int main() {
      tree t1;
    
      t1.recursive_insert(5);
      t1.recursive_insert(3);
      t1.insert(10);
      t1.insert(7);
      t1.recursive_insert(50);
      t1.recursive_insert(6);
      t1.recursive_insert(1);
      t1.recursive_insert(45);
      t1.recursive_insert(55);
      t1.recursive_insert(4);
    
      t1.print_inorder();
    
      if(t1.children_sum()) {
        cout<<"Tree satisfies children sum property"<<endl;
      } else {
        cout<<"Tree does not satisfy children sum property"<<endl;
      }
    
      t1.ensure_children_sum();
      t1.print_inorder();
    
      if(t1.children_sum()) {
        cout<<"Tree satisfies children sum property"<<endl;
      } else {
        cout<<"Tree does not satisfy children sum property"<<endl;
      }
    
      return 0;
    }
     

    1 3 4 5 6 7 10 45 50 55
    Tree does not satisfy children sum property
    1 5 4 111 6 6 106 45 100 55
    Tree satisfies children sum property

  • Durga Guntoju

    int makeItChildSumTree(struct node *root)
    {
    if(root)
    {
    int l_value=makeItChildSumTree(root->left);
    int r_value=makeItChildSumTree(root->right);
    if((root->left)||(root->right))
    if(root->data!=l_value+r_value)
    root->data=l_value+r_value;
    return root->data;
    }
    else return 0;
    }

  • Hanish

    We can optimise the code to work in O(n) time as:
    Logic:
    If a node’s data is smaller than the sum of its children, it wont ever become greater than them.
    If a node’s data is greater than sum of its children, we will increment the left(or right) child’s data Before calling convert_tree(node->left). Now when we will return to this node in postfix order, its children would have remained constant or increased i.e. either the node’s data is equal to or less than the sum of its childrern. So we need not call the increment function.

    Thus, the code works in O(n) time.

    Here is the optimised function :

    void convertTree(struct node* node)
    {
    int left_data = 0, right_data = 0, diff;
    if(node == NULL ||
    (node->left == NULL && node->right == NULL))
    return;
    else
    {
    if(node->left != NULL)
    left_data = node->left->data;

    if(node->right != NULL)
    right_data = node->right->data;

    diff = left_data + right_data – node->data;

    if(diff left);
    convertTree(node->right);

    if(node->left != NULL)
    left_data = node->left->data;

    if(node->right != NULL)
    right_data = node->right->data;

    diff = left_data + right_data – node->data;

    if(diff > 0)
    node->data = node->data + diff;
    }
    }

    void increment(struct node* node, int diff)
    {
    if(node->left != NULL)
    node->left->data = node->left->data + diff;
    else if (node->right != NULL)
    node->right->data = node->right->data + diff;
    }

  • Aditya

    Can it be done something like this in one function itself ?

    The adjustment in the case of diff < 0 will be done in the deepest node first
    and will be adjusted accordingly in the parent.

    int convertTree(Node *n, int delta = 0) {
    if (n == NULL) {
    return 0;
    }
    if (n->left == NULL && n->right == NULL) {
    n->data += delta; // Fix in the deepest node.
    return n->data;
    }
    int sum = convertTree(n->left, delta);
    sum += convertTree(n->right, delta);
    int diff = sum – n->data;
    if (diff == 0) { return n->data; }
    else if (diff > 0) {
    n->data += diff;
    return n->data;
    } else { //diff<0
    diff = -1 * diff;
    if (n->left) { convertTree(n->left, diff); }
    else if (n->right) { convertTree(n->right,diff); }
    }
    return n->data;
    }

  • Nikin
     
    
    void convertTree(node *sr)
    {
    if(sr == NULL)
    return;
    int lData = rData = 0;
    else
    {
    convertTree(sr->left);
    convertTree(sr->right);
    
    if(sr->left)
    lData = sr->left->data;
    if(sr->right)
    rData = sr->right->data;
    
    int diff = lData + rData - sr->data;
    
    if(diff>0)
    sr->data += diff;
    if(diff<0)
    increment(sr, -diff);
    
    }
    
    }
    
     
  • TC

    @GeekforGeeks,

    I think proposed solution may fail, if root value is less than sum of its children.

    Why can’t we visit left and right child of a root, after we did some processing rather than visiting children nodes before.

    That is I am suggesting for Top-down approach rather than bottom – up as proposed in given solution.

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
  • vaibhavbright

    better answer – takes O(n) time for all cases :)

    Algorithm — do a DFS traversal (mixture of pre and post) and is children_sum > node_value, update it. If the situation is reverse add this to current_index of array to_adjust.
    Now we are maintaining an array to_adjust to store the amount by which node_value is greater than children_sum. I am also using a static variable called index. So, the nodes(only the internal nodes) are given an index in a preorder fashion, i.e., when we reach that node we increment the index value to be given to the next node. And the to_adjust[index] is set after we have traversed left and right subtree ofcourse when we have their values.

    The second function/stage is another DFS when I am updating the children values accordingly. This is purely a pre-order type traversal.

    Both traversals take O(n) time. So, time complexity = O(n)

    Code is given below.

     
    int increment_node_data(node *current_node, int *to_adjust) {
        static int index = 0;
        if((current_node->left == NULL) && (current_node->right == NULL)) {
            return current_node->data;
        }
        int sum = 0;
        int current_index = index;
        index++;
        if(current_node->left != NULL)
            sum += increment_node_data(current_node->left, to_adjust);
        if(current_node->right != NULL)
            sum += increment_node_data(current_node->right, to_adjust);
        if(current_node->data < sum)
            current_node->data = sum;
        else
            to_adjust[current_index] = current_node->data - sum;
        return current_node->data;
    }
    
    void increment_child_data(node *current_node, int *to_adjust, int to_increment) {
        static int index = 0;
        current_node->data += to_increment;
        if((current_node->left != NULL) || (current_node->right != NULL)) {
            to_increment += to_adjust[index];
            index++;
            if(current_node->left != NULL) {
                increment_child_data(current_node->left, to_adjust, to_increment);
                to_increment = 0;
            }
            if(current_node->right != NULL)
                increment_child_data(current_node->right, to_adjust, to_increment);
        }
    }
    
    void tree::convert_to_children_sum_tree() {
        int *to_adjust = new int[100];
        increment_node_data(root, to_adjust);
        increment_child_data(root, to_adjust, 0);
    }
     

    call it simply by “t1.convert_to_children_sum_tree()” in main.

    Regards.

    Regards.

  • a2

    Is there any problem with the following recursive code ?

     
    #include<stdlib.h>
    
    typedef struct node{
    	int data;
    	struct node* left;
    	struct node* right;
    } node;
    
    node* newNode(int data)
    {
    	node* temp = (node*)malloc(sizeof(node));
    	temp->data=data;
    	temp->left=temp->right=NULL;
    	return temp;
    }
    
    node* createTree()
    {
    	node* root=newNode(50);
    	root->left=newNode(7);
    	root->left->left=newNode(3);
    	root->left->right=newNode(5);
    	root->right=newNode(2);
    	root->right->left=newNode(1);
    	root->right->right=newNode(30);
    	return root;
    }
    
    void print(node* node)
    {
       if(!node) return;
       print(node->left);
       printf(" %d ",node->data);
       print(node->right,1);
    }
    
    int Convert(node *root)
    {
    	if(!root) return 0;
    	if(!root->left && !root->right) return root->data;
    	Convert(root->left);
    	Convert(root->right);
    	if(root->left && root->right)
    	{
    		int l = root->left->data;
    		int r = root->right->data;
    		if(root->data < ( l + r ))
    		{
    			root->data += ( (l + r ) - root->data );
    		}
    		else
    		{
    			root->left->data += root->data - ( l + r ) ;
    			Convert(root->left);
    		}
    	}
    	if(!root->left && root->right)
    	{
    		int r = root->right->data;
    		if(root->data < r ) root->data += r - root->data;
    		else{
    			root->right->data += root->data - r;
    			Convert(root->right);
    		}
    	}
    	if(root->left && !root->right)
    	{
    		int l = root->left->data;
    		if(root->data < l) root->data += l - root->data;
    		else{
    			root->left->data += root->data - l;
    			Convert(root->left);
    		}
    	}
        return root->data;
    }
    
    int main()
    {
    	node* root=createTree();
    	print(root,1);
    	Convert(root);
    	printf("\nafter convert ....\n\n");
    	print(root,1);
    	return 0;
    }
    
    
     
    • a2

      Sorry , there has been some type errors in the the print function and to its call !

  • Nitin

    Please tell me if I am wrong but the question doesn’t say that we need to make the sum minimum also.If that is the case then we can simply calculate the maximum value once ( O(n) ), then we can make the value of all leaves equal to maximum value and propagate the sum of left, right child upwards (recursively).

  • GeeksforGeeks

    @All: We have fixed the increment function. If left subtree is not NULL, then it increments the left subtree. If left subtree is NULL, then it increments the right subtree. It recursively calls itself to fix the complete tree down. So the code now works for following type of trees.

       13
       /\
      4  6
       \
        4
    
  • Abhishek

    We can do the following recursively (Please tell me if i am wrong)

    void convert(tree_node *node)
    > convert(node->left)
    > convert(node->right)
    > node->data = sum(left, right)
    >return;

    Code given below (We can write the code for sum() where we can check if one node is NULL, we just return the other’s data, else we return the sum of the data of both)

     
    void convert(tree_node *node) {
      if(node == NULL) {
        return;
      }
    /* Take care if its a leaf node...just return */
      if((node->left == NULL) && (node->right == NULL)) {
        return;
      }
    
      /* Traverse postorder */
    
      convert(node->left);
      convert(node->right);
    
      node->data = sum(node->left, node->right);
      return;
    }
     
    • Abhishek

      Aaaaah!! got it! sorry for the wrong post.

  • Vijay

    I think the following need be added to increment function at the end of while loop to take care of cases like
    diff=3

       13
       /\
      4  6
       \ 
        4
    Without this line, result after applying increment function would be:
       13
       /\
      7  6
       \
        4
    
     
    if(node->right != NULL)
    {
        node->left = newNode(diff);
        return;
    }
     
  • amitp49

    Does it necessary to have unique tree after this conversion?
    i mean if somebody increment right child and resultant tree satisfy the Children sum property then will it be consider as right answer?

  • ada
     
    Cant you just do a Preorder, check if parent satisfy child sum pro if not increment left child and keep on repeating activity for subchilds...this way you will always increase values and also retain the prop and it will take a single pass only... please let me know if there is any flow i this...
     
  • Vikram
     
    /* Paste your code here (You may delete these lines if not writing code) */
    I think it has a very simple and elegant solution:
    
    
    Convert(node *head){
      if(head is not leaf){
        head->data = Convert(head->left) + Convert(head->right);
      }
      return head->data;
    }
    
    
     
    • Rahim

      You cannot decrement value of any node, remember? This does not guarantee that.

  • hari6988

    consider a tree like this
    7
    /
    3
    /
    2
    /
    1

    In this case, the diff is 1. So, u should just increment the value of root’s left node (node 3) to get a sum tree. But, in ur code, u will increment both 3 and 2 ,which will not give u a sum tree

    • hari6988

      sorry ,it was a stupid comment… i didn’t understand correctly

      • Adam

        when node data is greater than the sum of two of its children why aint we decreasing the node value rather increasing its left children…is there is some algorithm for doing so….or we doing just as it is!

  • jagannath
     
    #include<iostream>
    using namespace std;
    
    struct Node
    {
           int data;
           Node * lchild;
           Node * rchild;
    };
    
    typedef Node * Nodeptr;
    Node * create_node(int value)
    {
         Node * temp = new Node();
         temp->data = value;
         temp->lchild = NULL;
         temp->rchild = NULL;
         return temp;
    }
    
    int height_of_tree(Node * root)
    {
        if(root == NULL)
                return 0;
        int l = height_of_tree(root->lchild);
        int r = height_of_tree(root->rchild);
        
        if(l>r)
           return l+1;
        else
           return r+1;
    }
    
    void print_nodes_at_level_l_from_root(Node * root,int l)
    {
         if(root == NULL)
         {
             return;
         }
         if(l == 0)
             cout<data<lchild,l-1);
         print_nodes_at_level_l_from_root(root->rchild,l-1);
    }
    
    void update_node_values_with_child_sum_from_leaf_nodes(Node ** root)
    {
        if(*root == NULL)
                return ;
        
        update_node_values_with_child_sum_from_leaf_nodes(&(*root)->lchild);
        update_node_values_with_child_sum_from_leaf_nodes(&(*root)->rchild); 
        
        int root_value = (*root)->data;
        int lchild_value = ((*root)->lchild?(*root)->lchild->data:0);
        int rchild_value = ((*root)->rchild?(*root)->rchild->data:0);
        
        if(root_value data = (lchild_value + rchild_value);
        }   
    }
    
    void update_node_values_with_child_sum_from_root_nodes(Nodeptr *root)
    {
         if(*root == NULL )
                return ;
               
         int root_value = (*root)->data;
         int lchild_value;
         int rchild_value;
     
         lchild_value = ((*root)->lchild? (*root)->lchild->data:0);
         rchild_value = ((*root)->rchild? (*root)->rchild->data:0);
         
         int result = root_value - (lchild_value + rchild_value);
         if(result > 0 )
         {
                   if((*root)->lchild == NULL && (*root)->rchild != NULL )
                   {
                       (*root)->lchild->data += result;
                   }
                   else if((*root)->rchild == NULL && (*root)->lchild != NULL)
                   {
                       (*root)->lchild->data += result;
                   }
                   else if((*root)->lchild != NULL && (*root)->rchild != NULL)
                   {
                        if(lchild_value lchild->data += result;
                        }    
                        else
                        {
                         (*root)->rchild->data += result;
                        }
                   }
         }
    
         update_node_values_with_child_sum_from_root_nodes(&(*root)->lchild);
         update_node_values_with_child_sum_from_root_nodes(&(*root)->rchild);    
    }
    
    int main()
    {
         Nodeptr root = create_node(1);
         root->lchild       = create_node(2);
         root->rchild       = create_node(3);
         root->rchild->rchild = create_node(44);
         root->lchild->lchild  = create_node(4);
         root->lchild->rchild = create_node(5);
         root->lchild->lchild->lchild  = create_node(7);
         
         /*root = create_node(50);
         root->lchild       = create_node(7);
         root->rchild       = create_node(2);
         root->rchild->rchild = create_node(30);
         root->lchild->lchild  = create_node(3);
         root->lchild->rchild = create_node(5);
         root->rchild->lchild = create_node(1);*/
    
         update_node_values_with_child_sum_from_leaf_nodes(&root);
         update_node_values_with_child_sum_from_root_nodes(&root);
      
         int height = height_of_tree(root);
         for(int i=0;i<height;i++)
         {
            print_nodes_at_level_l_from_root(root,i);
            cout<<endl;
         }
         getchar();
         return 0;
    }
     

    Algorithms:

    Step1 : First i traverse the tree in postorder and check for the root nodes whose sum is less than the sum of its child nodes and if its less we update the value of root node and do the same thing for all the nodes.
    Step2: Now i traverse the tree in preorder and check , if root nodes value is greater than child nodes sum then update one of the child node value (child node = min(left child,right child)).

    Complexity:

    So i think complexity for my algorithm is O(n) as i am traversing the tree twice postorder and preorder.

    Correct me if i am wrong.

    • jagannath
       
      void update_node_values_with_child_sum_from_leaf_nodes(Node ** root)
      {
          if(*root == NULL)
                  return ;
          
          update_node_values_with_child_sum_from_leaf_nodes(&(*root)->lchild);
          update_node_values_with_child_sum_from_leaf_nodes(&(*root)->rchild); 
          
          int root_value = (*root)->data;
          int lchild_value = ((*root)->lchild?(*root)->lchild->data:0);
          int rchild_value = ((*root)->rchild?(*root)->rchild->data:0);
          
          if(root_value data = (lchild_value + rchild_value);
          }   
      }
      
      void  update_node_values_with_child_sum_from_root_nodes(Node **root)
      {
           if(*root == NULL )
                  return ;
                 
           int root_value = (*root)->data;
           int lchild_value;
           int rchild_value;
       
           lchild_value = ((*root)->lchild? (*root)->lchild->data:0);
           rchild_value = ((*root)->rchild? (*root)->rchild->data:0);
           
           int result = root_value - (lchild_value + rchild_value);
           if(result > 0 )
           {
                     if((*root)->lchild == NULL && (*root)->rchild != NULL )
                     {
                         (*root)->lchild->data += result;
                     }
                     else if((*root)->rchild == NULL && (*root)->lchild != NULL)
                     {
                         (*root)->lchild->data += result;
                     }
                     else if((*root)->lchild != NULL && (*root)->rchild != NULL)
                     {
                          if(lchild_value lchild->data += result;
                          }    
                          else
                          {
                           (*root)->rchild->data += result;
                          }
                     }
           }
      
           update_node_values_with_child_sum_from_root_nodes(&(*root)->lchild);
           update_node_values_with_child_sum_from_root_nodes(&(*root)->rchild);    
      }
       

      These are basics two functions which helps to form the child sum tree, need to call the functions in this order only.

      • jagannath
         
        void update_node_values_with_child_sum_from_leaf_nodes(Node ** root)
        {
               if(*root == NULL)
                     return ;
               
                update_node_values_with_child_sum_from_leaf_nodes
        (&(*root)->lchild);
             
                update_node_values_with_child_sum_from_leaf_nodes
        (&(*root)->rchild);                                                                                         
            int root_value = (*root)->data;
            int lchild_value =  ((*root)->lchild?(*root)->lchild->data:0);
            int rchild_value = ((*root)->rchild?(*root)->rchild->data:0);
            
             if(root_value < (lchild_value + rchild_value))
             {
                 (*root)-&gtdata = (lchild_value + rchild_value);
             }   
        }
        
        void  update_node_values_with_child_sum_from_root_nodes(Node **root)
        {
              if(*root == NULL )
                     return ;
                   
              int root_value = (*root)->data;
              int lchild_value;
              int rchild_value;
         
              lchild_value = ((*root)->lchild? (*root)->lchild->data:0);
              rchild_value = ((*root)->rchild? (*root)->rchild->data:0);
             
              int result = root_value - (lchild_value + rchild_value);
              if(result > 0 )
              {
                       if((*root)->lchild == NULL && (*root)->rchild != NULL )
                       {
                           (*root)->lchild->data += result;
                       }
                       else if((*root)->rchild == NULL && (*root)->lchild != NULL)
                       {
                           (*root)->lchild->data += result;
                       }
                       else if((*root)->lchild != NULL && (*root)->rchild != NULL)
                       {
                            if(lchild_value < rchild_value)
                            {
                                 (*root)->lchild->data += result;
                            }    
                            else
                            {
                             (*root)->rchild->data += result;
                            }
                       }
             }
        
             update_node_values_with_child_sum_from_root_nodes(&(*root)->lchild);
             update_node_values_with_child_sum_from_root_nodes(&(*root)->rchild);    
        }
         

        These are basics two functions which helps to form the child sum tree, need to call the functions in this order only.

        Sorry for spaming.

  • devendra088

    there is a typo at line : if diff < 0 (node’s data is smaller than the node's children sum) … it should be if diff < 0 (node’s data is larger than the node's children sum)

  • Shri

    In the increment function I think you should create the node with the diff after fixing the left subtree.. So increment function should be like…

     
    void increment(struct node* node, int diff)
    {
     
      /* Go in depth, and fix all left children */
      while(node->left != NULL)
      {
        node->left->data = node->left->data + diff;
        node = node->left;
      }
    
      /* This if is for the case where left child is NULL */
      if(node->left == NULL)
      {
        node->left = newNode(diff);
        return;
      }
    }
     
    • Shri

      Or before creating check if we haven’t reached at leaf node(i.e. right child exist).

  • vibhav3008
     
    void increment(node * root,int data)
    {
        node *current=root;
        while(current!=NULL)
        {
            current->data+=data;
            if(current->left!=NULL)
            {
                current=current->left;
            }
            else
                current=current->right;
        }
        delete current;
    }
    
    void binarytochildsum(node *root)
    {
        int rdata=0,ldata=0;
        if((root->left==NULL && root->right==NULL) || root==NULL) //Leaf node
            return;
        binarytochildsum(root->left);
        binarytochildsum(root->right);
        if(root->right!=NULL)
        {
            rdata=root->right->data;
        }
        if(root->left!=NULL)
        {
            ldata=root->left->data;
        }
        int diff=root->data - (rdata+ldata);
        if(diffdata-=diff;
        }
        else
        {
            if(root->left!=NULL)
                increment(root->left,diff);
            else
                increment(root->right,diff);
        }
        return;
    }
     
    • vibhav3008

      Please comment on this solution. It retains the structure of the tree.

      • Sandeep

        @vibhav3008:

        Could you please provide code of main() that you used to test your code. Also, please add few words about your approach.

        • Cracker

          @sandeep…i think its complexity is O(nj)..why r saying its O(n^2)..?? can u please explain..??

  • gauravs

    Why not Increment the value of the right node if left node is not present instead of creating the left node…

  • coderyogi

    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.

    • Harsh

      Yes, i agree.

      Could anyone provide an algorithm where the structure of the tree is not changed.

  • Jyothiq

    Sorry, Missed the statement “you can only increment data values in any node”. Now its working fine

    Thanks

  • GeeksforGeeks

    @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.

  • Jyothi

    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?