Maximum width of a Binary Tree with null values


A binary tree is defined as a tree data structure where each has at most two children.

The width of a binary tree for a level is defined as the number of nodes between the rightmost and leftmost nodes of that level, including the NULL nodes that come in between.

The maximum width of a binary tree is defined as the maximum of all the widths at each level of the binary tree.

In this first approach, we represent the binary tree as an array representation of the Heap data structure. At each level, the width of that level will be the difference between the index of the rightmost child in the array and the index of the leftmost child in the array. Afterwards, we just need to find the maximum of these width values.

In the second approach, we use level order traversal by giving an id to each node according to their parent. The width at each level will be the difference between the id of the last node at that level and the id of the first node at that level. Then, we can take the maximum of these values as the answer

Problem statement - Given a binary tree consisting of N nodes, we need to find the maximum width of the binary tree with null values where the maximum width is defined as the maximum of all the widths at each level.

Sample Examples

Input

       11
      /  \
     23   13
    / \    \
  14  54   46
  /   /
 27  38

Output

4

Explanation

The width of the first level 1.

The width of the second level is 2.

The width of the third level is 4.

The width of the fourth level is 3.

Therefore, the maximum width is the maximum of all these values −

max{1,2,4,3} = 4.

Input

 1
  \
   12
    \
     36

Output

1

Explanation

The width of each level is 1. So, the answer is 1.

Input

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

Output

8

Explanation

The width of the first level is 1.

The width of the second level is 2.

The width of the third level is 4.

The width of the fourth level is 8.

Hence, the maximum width is 8.

Approach 1

In this approach, we will represent the Binary Tree with the help of the Heap data structure through the agency of its array form. If there is a node with index i, then its children would be at the indices (2*i+1) and (2*i+2). Now the width of every level is given by the difference of index of rightmost child and the index of the leftmost child at that level. To find the maximum width, we just take the maximum of all these widths.

Algorithm

  • Step 1 − Create a tree struct, Tree.

  • Step 1.1 − Tree will have an integer, val, and two pointers to itself, left and right.

  • Step 2 − Create two hashmaps, mx_ind and mn_ind, that stores the position of the extreme nodes (the leftmost and the rightmost) at each level.

  • Step 3 − Design and create a recursive method, fill_maps, to fill in the hashmaps.

  • Step 3.1 − If the root is NULL, then return.

  • Step 3.2 − Store the leftmost and rightmost value of index at each level in mn_ind and mx_ind

  • Step 3.3 − Recursively call the left child of the node by updating the level by level + 1 and the index by 2*index + 1.

  • Step 3.4 − Recursively call the right child of the node by updating the level by level + 1 and the index by 2*index + 2.

  • Step 4 − Call the function, fill_maps, to fill in the hashmaps.

  • Step 5 − Traverse the hashmaps, and return the maximum value of mx_ind[L] - mn_ind[L] + 1.

Example

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
struct Tree {
   int val;
   Tree *left, *right;
   // Constructor
   Tree(int item){
      val = item;
      left = right = NULL;
   }
};
map<int,int> mx_ind;
map<int,int> mn_ind;
//Function to fill the maps
void fill_maps(Tree* node,int level,int ind){
   // Base case
   if(node==NULL)return;
   if(mx_ind.count(level))mx_ind[level] = max(ind,mx_ind[level]);
   else mx_ind[level] = ind;
   if(mn_ind.count(level))mn_ind[level] = min(ind,mn_ind[level]);
   else mn_ind[level] = ind;
   // Recursively call the function for the left and the right child
   fill_maps(node->left, level+1, 2*ind+1);
   fill_maps(node->right, level+1, 2*ind+2);
}
int MaxWidth(Tree* root){
   int ans = 0;
   fill_maps(root,0,0);
   // Get the maximum width from width of all levels
   for(auto lvl:mx_ind)ans = max(ans,mx_ind[lvl.first]-mn_ind[lvl.first]+1);
   return ans;
}
int main(){
   /*
   Constructed Binary Tree
             1
           /  \
          2    3
         /      \
        4        5
       /          \
      6            7
   */
   struct Tree* root = new Tree(1);
   root->left = new Tree(2);
   root->right = new Tree(3);
   root->left->left = new Tree(4);
   root->right->right = new Tree(5);
   root->left->left->left = new Tree(6);
   root->right->right->right = new Tree(7);
   int ans = MaxWidth(root);
   cout<<ans<<'\n';
   return 0;
}

Output

8

Time complexity − O(n), where n is the number of nodes in the tree.

Space complexity − O(n), to store the leftmost and rightmost node at each level.

Approach 2

In this approach, we will use level order traversal and give an ID to all nodes using the ID of their corresponding parent node. For each level, we can calculate the width of that level by subtracting the width of the last node at that level from the id of the first node. Then, we can take the maximum of all the width values to get our required result.

Algorithm

  • Step 1 − Create a tree struct, Tree.

  • Step 1.1 − Tree will have an integer, val, and two pointers to itself, left and right.

  • Step 2 − Create a queue data structure.

  • Step 2.1 − The queue will contain a pair containing pointer to a node, and its corresponding ID.

  • Step 3 − Do a level order traversal of the tree.

  • Step 3.1 − At each level, store the ID of the first and last nodes in two variables.

  • Step 3.2 − At each node in a level, push the left and right child of the node to the queue with ID 2*i + 1 and 2*i + 2.

  • Step 3.3 − The value of the width of that level is calculated as last_node_ID - first_node_ID + 1.

  • Step 3.4 − Take the maximum of all values of the width to get the maximum width.

  • Step 4 − Return the answer.

Example

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct Tree {
   int val;
   Tree *left, *right;
   // Constructor
   Tree(int item){
      val = item;
      left = right = NULL;
   }
};
int MaxWidth(Tree* root){
   int ans = 0;
   //Base Case
   if(root==NULL)return ans;
   queue<pair<Tree*,int>> que;
   ans = 1;
   que.push(make_pair(root,0));
   //Level order traversal
   while(!que.empty()){
      int sz = que.size();
      int first , last;
      for(int i=0;i<sz;i++){
         Tree *curr = que.front().first;
         int id = que.front().second;
         que.pop();
         //First Node
         if(i==0)first=id;
         //Last Node
         if(i==(sz-1))last=id;
         if(curr->left!=NULL)que.push(make_pair(curr->left,2*id+1));
         if(curr->right!=NULL)que.push(make_pair(curr->right,2*id+2));
      }
      // Taking the maximum of the width at each level
      ans = max(ans,last-first+1);
   }
   return ans;
}
int main(){
   /*
   Constructed Binary Tree
             1
           /  \
          2    3
         /      \
        4        5
       /          \
      6            7
   */
   struct Tree* root = new Tree(1);
   root->left = new Tree(2);
   root->right = new Tree(3);
   root->left->left = new Tree(4);
   root->right->right = new Tree(5);
   root->left->left->left = new Tree(6);
   root->right->right->right = new Tree(7);
   int ans = MaxWidth(root);
   cout<<ans<<'\n';
   return 0;
}

Output

8

Time complexity − O(n), where n is the number of nodes in the tree.

Space complexity − O(n), to store the leftmost and rightmost node at each level.

Updated on: 01-Nov-2023

70 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements