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


In this problem, we will update the level of each child node based on the left and right subtree's weight difference.

Here, we will recursively traverse the subtree of each node to get the weight of the left and right subtree. After that, we will again traverse each subtree node to update its level according to the difference in weight of the left and right sub-tree.

Problem Statement

We have given a complete binary tree containing N levels and 2N -1 nodes. The levels are numbered from 0 to N − 1 in decreasing order (0, -1, -2, -3, etc.). We need to update the level of all child nodes of each node based on the difference in the weight of the left and right subtree. Here, the weight of the subtree is the sum of the values of all nodes.

  • Increment the levels of each node of the lighter subtree by weight difference.

  • Decrement the levels of each node of the heavier subtree by weight difference.

Sample Examples

Input

N = 2
	1
 /   \
2     3

Output

0, 0, -2

Explanation

  • The initial level of each node is [0, -1, -1].

  • The root node's level remains unchanged.

  • The weight of the left subtree for node '1' is 2, and the right subtree is 3. So, the weight difference is 1.

  • When we increase the level of each node of the lighter subtree by 1, the level of 2 becomes 0 from -1.

  • When we decrease the level of each node of the heavier subtree by 1, the level of 3 becomes -2 from -1.

Input

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

Output

0, 4, -6, 4, 2, -6, -8

Explanation

  • The initial level of each node is [0, -1, -1, -2, -2, -2, -2].

  • For node 1, the weight of the left subtree is 11, and the right subtree is 16. So, we will increase the level of each left subtree node by 5 and decrease the level of each right subtree node by 5.

  • Updated levels are [0, 4, -6, 3, 3, -7, -7].

  • For node 2, the weight difference is 1. So, we need to update the level of 4 and 5 nodes.

  • For node 3, the weight difference is 1. So, we need to update levels 6 and 7.

  • The final levels are [0, 4, -6, 4, 2, -6, -8].

Approach

In this approach, we will get the weight of the left and right subtree for each node of the binary tree. After that, we will update the level of each subtree node by the weight difference according to whether the tree is lighter or heavier. As we have a complete binary tree, the left tree will always be lighter, and the right tree always be heavier.

Algorithm

  • Step 1 − Define the weights array and insert the initial weight of the binary tree. Also, insert the initial levels of each node into the levels[] array.

  • Step 2 − Call the createCBT() function to create a complete binary tree.

  • Step 2.1 − In the createCBT() function, traverse the weight array and call the insertNode() function to insert a node of the given weight.

  • Step 2.1.1 − In the insertNode() function, create a new TreeNode.

  • Step 2.1.2 − If the head node is null, assign a new node to the head node. Otherwise, if the left child of the front node of the queue is null, insert a new node as a left child. Else, insert a new node as a right child and pop up the front node from the queue.

  • Step 2.1.3 − Insert the newNode into the queue and return the head node.

  • Step 2.2 − Update the head node in each iteration, and return it at the end of the function.

  • Step 3 − Now, execute the calcualteLevel() function to calculate the levels.

  • Step 3.1 − If the binary tree is null, return from the function.

  • Step 3.2 − Execute the getWeight() function to get the weight of the left and right subtree.

  • Step 3.2.1 − In the getWeight() function, add the weight of the current node with the left subtree's and right subtree's weight and return it from the function.

  • Step 3.3 − Take the weight difference.

  • Step 3.4 − Call the updateLevels() function to update each subtree node with the weight difference.

  • Step 3.4.1 − In the updateLevels() function, add weight difference to the current node's value, and make the recursive call for the left and right subtree.

  • Step 3.5 − Make a recursive call of calculateLevels() function for the left and right subtree.

  • Step 4 − Execute the printLevels() function to print levels of all nodes. In the printLevels() function, we traverse the complete binary tree recursively and print the updated level of each nodes.

Example

#include <bits/stdc++.h>
using namespace std;

struct TreeNode {
   // To store weight and level
   int weight;
   int level;

   // Left and right pointer
   struct TreeNode *left;
   struct TreeNode *right;

   TreeNode(int wei, int level) {
      this->weight = wei;
      this->level = level;
      left = right = NULL;
   }
};

// For inserting a node into a tree
struct TreeNode *insertNode(struct TreeNode *head, int weight, int level, queue<TreeNode *> &que) {
   struct TreeNode *new_node = new TreeNode(weight, level);
   if (head == NULL)
      head = new_node;

   // If the left node is empty, insert a new node as a left child
   else if (que.front()->left == NULL) {
      que.front()->left = new_node;
   } else {
      // Insert new node as a right child
      que.front()->right = new_node;
      que.pop();
   }
   // Insert node into the queue
   que.push(new_node);
   return head;
}

struct TreeNode *createCBT(vector<int> wei, vector<int> lev) {
   struct TreeNode *head = NULL;
   // initialize a queue of nodes
   queue<TreeNode *> que;
   int len = wei.size();
   for (int p = 0; p < len; p++) {
      // Insert node into the tree
      head = insertNode(head, wei[p], lev[p], que);
   }
   return head;
}

int getWeight(struct TreeNode *head) {
   // Weight is 0 for the head node
   if (head == NULL)
      return 0;
   return head->weight + getWeight(head->left) + getWeight(head->right);
}
void updateLevels(struct TreeNode *head, int m) {
   if (head == NULL)
      return;
   // Change the level of the current node
   head->level = head->level + m;
   // Update the level of each node of the subtree
   updateLevels(head->left, m);
   updateLevels(head->right, m);
}

void calcualteLevel(struct TreeNode *head) {
   if (head == NULL)
      return;
   int leftWeight = getWeight(head->left);
   int rightWeight = getWeight(head->right);
   // Get weight difference
   int weightDiff = leftWeight - rightWeight;
   // Update the levels
   updateLevels(head->left, -weightDiff);
   updateLevels(head->right, weightDiff);
   // Recursive call for subtrees
   calcualteLevel(head->left);
   calcualteLevel(head->right);
}
void PrintLevels(struct TreeNode *head) {
   if (head == NULL)
      return;
   queue<TreeNode *> que;
   que.push(head);
   while (!que.empty()) {
      cout << que.front()->level << " ";
      if (que.front()->left != NULL)
         que.push(que.front()->left);
      if (que.front()->right != NULL)
         que.push(que.front()->right);
      que.pop();
   }
   cout << endl;
}
// Driver code
int main() {
   // Number of levels
   int N = 3;
   int nodes = pow(2, N) - 1;
   // Defining the weight of each node
   vector<int> weights;
   for (int p = 1; p <= nodes; p++) {
      weights.push_back(p);
   }
   vector<int> levels;
   // Defining the level of each node
   for (int p = 0; p < N; p++) {
      for (int q = 0; q < pow(2, p); q++) {
         // value of level becomes negative
         // While going down the head
         levels.push_back(-1 * p);
      }
   }
   // Create a complete binary tree
   struct TreeNode *head = createCBT(weights, levels);
   calcualteLevel(head);
   PrintLevels(head);
   return 0;
}

Output

0 4 -6 4 2 -6 -8
  • Time complexity − O(N)

  • Space complexity − O(N)

Updated on: 25-Aug-2023

42 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements