Print updated levels of each node of a Complete Binary Tree based on difference in weights of subtrees

Given a complete binary tree with N levels numbered [0, (N – 1 )] from root to the lowest level in decreasing order and having weights numbered between [1, 2N – 1] from the root to the last leaf node in the increasing order, the task for every node is to adjust the values of the levels of all nodes present in its left and right subtree based on the following condition:

  • Increase the level of all the nodes of lighter subtree by the difference of their weights.
  • Decrease the level of all the nodes of heavier subtree by the difference of their weights.

Examples:

Input:

          1
        /   \
       2     3

Output: 0 0 -2
Explanation:
The initial levels of the nodes {1,2,3} are {0,-1,-1} respectively.
The root node remains unchanged.
The weight of left subtree is 2 and the weight of the right subtree is 3.
So, the left subtree goes up by (3 – 2) = 1 level to 0.
The right subtree goes down by 1 level to -2.

Input:



             1
           /   \
          2     3
         / \   / \
        4   5 6   7

Output: 0 4 -6 4 2 -6 -8
Explanation:
The initial levels of the nodes {1,2,3,4,5,6,7} are {0,-1,-1,-2,-2,-2,-2} respectively.
The root node remains unchanged.
The weight of the left subtree {2,4,5} is 11.
The weight of the right subtree {3,6,7} is 16.
Hence all the nodes in left subtree move up by 5 while those in the right subtree moves down by 5.
Thus, the new levels of every node are:
Node 2: -1 + 5 = 4
Node 3: -1 – 5 = -6
Node 4,5: -2 + 5 = 3
Node 6,7: -2 – 5 = -7
Now, nodes 4,5 further based on the difference of their weights (5 -4 ) = 1.
Node 4: 3 + 1 = 4
Node 5: 3 – 1 = 2
Similarly, nodes 6,7 also get adjusted.
Node 6: -7 + 1 = -6
Node 7: -7 – 1 = -8
Hence the final adjusted levels of all the nodes are 0 4 -6 4 2 -6 -8.

Approach: In order to solve this problem, we calculate the weights of the left (w_left) and right (w_right) subtrees for every node and store their difference K. Once calculated, we recursively increase the value of the level of all the nodes of its lighter subtree by K and decrease that of its heavier subtree by K from their respective current values. Once computed for all nodes, we display the final values of level of every node.

Below code is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to print updated levels
// of each node of a Complete Binary Tree
// based on difference in weights of subtrees 
  
#include <bits/stdc++.h>
using namespace std;
  
// Node for the given binary tree
struct node {
  
    int weight;
  
    // stores the weight of node
    int level; 
  
    // stores the level of node
    struct node* left;
    struct node* right;
  
    node(int w, int l)
    {
        this->weight = w;
        this->level = l;
        left = right = NULL;
    }
};
  
// Utility function to insert a node
// in a tree rooted at root
struct node* insert(struct node* root,
 int n_weight, 
int n_level, queue<node*>& q)
{
  
    struct node* n 
= new node(n_weight, n_level);
  
    // if the tree is empty till now
    // make node n the root
    if (root == NULL)
        root = n;
  
    // If the frontmost node of 
    // queue has no left child
    // make node n its left child
    // the frontmost node still 
    // remains in the queue because
    // its right child is null yet
    else if (q.front()->left == NULL) {
        q.front()->left = n;
    }
  
    // Make node n the right child of
    // the frontmost node and remove 
    // the front node from queue
    else {
        q.front()->right = n;
        q.pop();
    }
    // push the node n into queue
    q.push(n);
  
    return root;
}
  
// Function to create a complete binary tree
struct node* createTree(vector<int> weights, 
vector<int> levels)
{
  
    // initialise the root node of tree
    struct node* root = NULL;
  
    // initialise a queue of nodes
    queue<node*> q;
  
    int n = weights.size();
    for (int i = 0; i < n; i++) {
  
        /*
        keep inserting nodes with weight values 
        from the weights vector and level values
        from the levels vector
        */
        root = insert(root, weights[i], 
        levels[i], q);
    }
    return root;
}
  
// Function to print final levels of nodes
void printNodeLevels(struct node* root)
{
  
    if (root == NULL)
        return;
  
    queue<node*> q;
    q.push(root);
  
    while (!q.empty()) {
  
        cout << q.front()->level << " ";
  
        if (q.front()->left != NULL)
            q.push(q.front()->left);
        if (q.front()->right != NULL)
            q.push(q.front()->right);
        q.pop();
    }
    cout << endl;
}
  
// Function to find the weight of subtree
int findWeight(struct node* root)
{
    // If the root node is null
    // then weight of subtree will be 0
    if (root == NULL)
        return 0;
      
    return root->weight + 
        findWeight(root->left)
        + findWeight(root->right);
}
  
// Function to compute new level
// of the nodes based on the
// difference of weight K
void changeLevels(struct node* root, int k)
{
  
    if (root == NULL)
        return;
      
    // Change the level of root node
    root->level = root->level + k;
  
    // Recursively change the level of
    // left and right subtree
    changeLevels(root->left, k);
    changeLevels(root->right, k);
}
  
// Function to calculate weight of
// the left and the right subtrees and 
// adjust levels based on their difference
void adjustLevels(struct node* root)
{
  
    // No adjustment required 
    // when root is null
    if (root == NULL)
        return;
  
    // Find weights of left 
    // and right subtrees
    int w_left = findWeight(root->left);
    int w_right = findWeight(root->right);
  
    // find the difference between the
    // weights of left and right subtree
    int w_diff = w_left - w_right;
  
    // Change the levels of nodes
    // according to weight difference at root
    changeLevels(root->left, -w_diff);
    changeLevels(root->right, w_diff);
  
    // Recursively adjust the levels
    // for left and right subtrees
    adjustLevels(root->left);
    adjustLevels(root->right);
}
  
// Driver code
int main()
{
    // Number of levels
    int N = 3;
  
    // Number of nodes
    int nodes = pow(2, N) - 1;
  
    vector<int> weights; 
    // Vector to store weights of tree nodes
    for (int i = 1; i <= nodes; i++) {
        weights.push_back(i);
    }
      
    vector<int> levels;
    // Vector to store levels of every nodes
    for (int i = 0; i < N; i++) {
  
        // 2^i nodes are present at ith level
        for (int j = 0; j < pow(2, i); j++) {
  
            // value of level becomes negative
            // while going down the root
            levels.push_back(-1 * i);
        }
    }
      
    // Create tree with the
// given weights and levels
    struct node* root 
= createTree(weights, levels);
      
    // Adjust the levels
    adjustLevels(root);
      
    // Display the final levels
    printNodeLevels(root);
      
    return 0;
}

chevron_right


Output:

0 4 -6 4 2 -6 -8

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.