Given a Binary Indexed Tree with N nodes except root node 0 (Numbered from 1 to N), Find its diameter.
Binary Indexed Tree is a tree where parent of a node number X = X – (X & (X – 1)) i.e. last bit is unset in X. The diameter of a tree is the longest simple path between any two leaves.
Examples:
Input: N = 12
Output: 6
Explanation: Path from node 7 to node 11.Input : n = 15
Output : 7
Approach:
- In a BIT, root is always node 0. In first level, all nodes are of power of 2 . (1, 2, 4, 8, ….)
- Consider any node in the first level (1, 2, 4, 8, ) its sub-tree will include all the nodes which has same number of bits as that of the root.
- Sub-Tree with root 1 will have no child.
- Sub-Tree with root 2 will have 3 as a child.
- Sub-Tree with root 4 will have 5, 6, 7 as a child.
- Sub-Tree with root 8 will have 9, 10, 11, 12, 13, 14, 15 as a child. (Double the size of the previous subtree)
- So subtree with root K will have K nodes including root. And the height of each subtree would be equal:
- for subtree with root 1
- for subtree with root 2
- for subtree with root 4
- Now, we need to find the subtree in which N lies. Say, the height of subtree just before the subtree in which N lies is H and size is L. So, the following cases are possible :
- Case 1 : When N >= L*2 – 1, in such a scenario N is in last level of its subtree. Thus, the diameter will be 2*H + 1. (Path from the lowest level leaf of the previous subtree to the N ).
- Case 2 : When N >= L + L/2 – 1, in such a scenario N is at level H in its subtree. Thus, diameter will be 2*H.
- Case 3 : Otherwise, it is optimal to consider the maximum path length between leaf nodes of two subtree just before the subtree in which N lies i.e diameter is 2*H – 1.
Below are the implementation of the above approach:
#include <bits/stdc++.h> using namespace std;
// Function to find diameter // of BIT with N + 1 nodes int diameter( int n)
{ // L is size of subtree just before subtree
// in which N lies
int L, H, templen;
L = 1;
// H is the height of subtree just before
// subtree in which N lies
H = 0;
// Base Cases
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
if (n == 3) {
return 3;
}
// Size of subtree are power of 2
while (L * 2 <= n) {
L *= 2;
H++;
}
// 3 Cases as explained in Approach
if (n >= L * 2 - 1)
return 2 * H + 1;
else if (n >= L + (L / 2) - 1)
return 2 * H;
return 2 * H - 1;
} // Driver Code int main()
{ int n = 15;
cout << diameter(n) << endl;
} |
// Java implementation of the approach class GFG
{ // Function to find diameter // of BIT with N + 1 nodes static int diameter( int n)
{ // L is size of subtree just before subtree
// in which N lies
int L, H, templen;
L = 1 ;
// H is the height of subtree just before
// subtree in which N lies
H = 0 ;
// Base Cases
if (n == 1 ) {
return 1 ;
}
if (n == 2 ) {
return 2 ;
}
if (n == 3 ) {
return 3 ;
}
// Size of subtree are power of 2
while (L * 2 <= n) {
L *= 2 ;
H++;
}
// 3 Cases as explained in Approach
if (n >= L * 2 - 1 )
return 2 * H + 1 ;
else if (n >= L + (L / 2 ) - 1 )
return 2 * H;
return 2 * H - 1 ;
} // Driver Code public static void main(String []args)
{ int n = 15 ;
System.out.println(diameter(n));
} } // This code contributed by PrinciRaj1992 |
# Python3 implementation of the approach # Function to find diameter # of BIT with N + 1 nodes def diameter(n):
# L is size of subtree just before
# subtree in which N lies
L, H, templen = 0 , 0 , 0 ;
L = 1 ;
# H is the height of subtree just before
# subtree in which N lies
H = 0 ;
# Base Cases
if (n = = 1 ):
return 1 ;
if (n = = 2 ):
return 2 ;
if (n = = 3 ):
return 3 ;
# Size of subtree are power of 2
while (L * 2 < = n):
L * = 2 ;
H + = 1 ;
# 3 Cases as explained in Approach
if (n > = L * 2 - 1 ):
return 2 * H + 1 ;
elif (n > = L + (L / 2 ) - 1 ):
return 2 * H;
return 2 * H - 1 ;
# Driver Code n = 15 ;
print (diameter(n));
# This code is contributed by Rajput-Ji |
// C# implementation of the approach using System;
class GFG
{ // Function to find diameter // of BIT with N + 1 nodes static int diameter( int n)
{ // L is size of subtree just before subtree
// in which N lies
int L, H;
L = 1;
// H is the height of subtree just before
// subtree in which N lies
H = 0;
// Base Cases
if (n == 1)
{
return 1;
}
if (n == 2)
{
return 2;
}
if (n == 3)
{
return 3;
}
// Size of subtree are power of 2
while (L * 2 <= n)
{
L *= 2;
H++;
}
// 3 Cases as explained in Approach
if (n >= L * 2 - 1)
return 2 * H + 1;
else if (n >= L + (L / 2) - 1)
return 2 * H;
return 2 * H - 1;
} // Driver Code public static void Main(String []args)
{ int n = 15;
Console.WriteLine(diameter(n));
} } // This code is contributed by 29AjayKumar |
7
Recommended Posts:
- Diameter of a Binary Tree
- Diameter of a Binary Tree in O(n) [A new method]
- Binary Indexed Tree : Range Updates and Point Queries
- Finding the lexicographically smallest diameter in a binary tree
- Sum of all nodes in a binary tree
- Sum of all leaf nodes of binary tree
- XOR of path between any two nodes in a Binary Tree
- Sink even nodes in Binary Tree
- Sum of nodes in the right view of the given binary tree
- Sink Odd nodes in Binary Tree
- Product of all nodes in a Binary Tree
- Sum of all the Boundary Nodes of a Binary Tree
- Sum of nodes in top view of binary tree
- Print Nodes in Top View of Binary Tree
- Print nodes in top view of Binary Tree | Set 2
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.