# Find the largest Perfect Subtree in a given Binary Tree

Given a Binary Tree, the task is to find the size of largest Perfect sub-tree in the given Binary Tree.
Perfect Binary Tree – A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at the same level.

Examples:

```Input:
1
/   \
2     3
/  \   /
4    5 6
Output:
Size : 3
Inorder Traversal : 4 2 5
The following sub-tree is the maximum size Perfect sub-tree
2
/  \
4    5

Input:
50
/      \
30         60
/   \      /    \
5    20   45      70
/  \     /  \
10   85  65  80
Output:
Size : 7
Inorder Traversal : 10 45 85 60 65 70 80
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: Simply traverse the tree in bottom up manner. Then on coming up in recursion from child to parent, we can pass information about sub-trees to the parent. The passed information can be used by the parent to do Prefect Tree test (for parent node) only in constant time. A left sub-tree need to tell the parent whether it is a Perfect Binary Tree or not and also need to pass max height of the Perfect Binary Tree coming from left child. Similarly, the right sub-tree also needs to pass max height of Prefect Binary Tree coming from right child.
The sub-trees need to pass the following information up the tree for finding the largest Perfect sub-tree so that we can compare the maximum height with the parent’s data to check the Perfect Binary Tree property.

1. There is a bool variable to check whether the left child or the right child sub-tree is Perfect or not.
2. From left and right child calls in recursion we find out if parent sub-tree if Prefect or not by following 2 cases:
• If both left child and right child are perfect binary tree and have same heights then parent is also a Perfect Binary Tree with height plus one of its child.
• If the above case is not true then parent cannot be perfect binary tree and simply returns max size Perfect Binary Tree coming from left or right sub-tree by comparing their heights.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` ` `  `// Node structure of the tree ` `struct` `node { ` `    ``int` `data; ` `    ``struct` `node* left; ` `    ``struct` `node* right; ` `}; ` ` `  `// To create a new node ` `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; ` `}; ` ` `  `// Structure for return type of ` `// function findPerfectBinaryTree ` `struct` `returnType { ` ` `  `    ``// To store if sub-tree is perfect or not ` `    ``bool` `isPerfect; ` ` `  `    ``// Height of the tree ` `    ``int` `height; ` ` `  `    ``// Root of biggest perfect sub-tree ` `    ``node* rootTree; ` `}; ` ` `  `// Function to return the biggest ` `// perfect binary sub-tree ` `returnType findPerfectBinaryTree(``struct` `node* root) ` `{ ` ` `  `    ``// Declaring returnType that ` `    ``// needs to be returned ` `    ``returnType rt; ` ` `  `    ``// If root is NULL then it is considered as ` `    ``// perfect binary tree of height 0 ` `    ``if` `(root == NULL) { ` `        ``rt.isPerfect = ``true``; ` `        ``rt.height = 0; ` `        ``rt.rootTree = NULL; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Recursive call for left and right child ` `    ``returnType lv = findPerfectBinaryTree(root->left); ` `    ``returnType rv = findPerfectBinaryTree(root->right); ` ` `  `    ``// If both left and right sub-trees are perfect and ` `    ``// there height is also same then sub-tree root ` `    ``// is also perfect binary subtree with height ` `    ``// plus one of its child sub-trees ` `    ``if` `(lv.isPerfect && rv.isPerfect && lv.height == rv.height) { ` `        ``rt.height = lv.height + 1; ` `        ``rt.isPerfect = ``true``; ` `        ``rt.rootTree = root; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Else this sub-tree cannot be a perfect binary tree ` `    ``// and simply return the biggest sized perfect sub-tree ` `    ``// found till now in the left or right sub-trees ` `    ``rt.isPerfect = ``false``; ` `    ``rt.height = max(lv.height, rv.height); ` `    ``rt.rootTree = (lv.height > rv.height ? lv.rootTree : rv.rootTree); ` `    ``return` `rt; ` `} ` ` `  `// Function to print the inorder traversal of the tree ` `void` `inorderPrint(node* root) ` `{ ` `    ``if` `(root != NULL) { ` `        ``inorderPrint(root->left); ` `        ``cout << root->data << ``" "``; ` `        ``inorderPrint(root->right); ` `    ``} ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``// Create tree ` `    ``struct` `node* root = newNode(1); ` `    ``root->left = newNode(2); ` `    ``root->right = newNode(3); ` `    ``root->left->left = newNode(4); ` `    ``root->left->right = newNode(5); ` `    ``root->right->left = newNode(6); ` ` `  `    ``// Get the biggest sizes perfect binary sub-tree ` `    ``struct` `returnType ans = findPerfectBinaryTree(root); ` ` `  `    ``// Height of the found sub-tree ` `    ``int` `h = ans.height; ` ` `  `    ``cout << ``"Size : "` `<< ``pow``(2, h) - 1 << endl; ` ` `  `    ``// Print the inorder traversal of the found sub-tree ` `    ``cout << ``"Inorder Traversal : "``; ` `    ``inorderPrint(ans.rootTree); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the approach ` `import` `java.util.*; ` ` `  `class` `GFG  ` `{ ` `     `  `// Node structure of the tree ` `static` `class` `node ` `{ ` `    ``int` `data; ` `    ``node left; ` `    ``node right; ` `}; ` ` `  `// To create a new node ` `static` `node newNode(``int` `data) ` `{ ` `    ``node node = ``new` `node(); ` `    ``node.data = data; ` `    ``node.left = ``null``; ` `    ``node.right = ``null``; ` `    ``return` `node; ` `}; ` ` `  `// Structure for return type of ` `// function findPerfectBinaryTree ` `static` `class` `returnType  ` `{ ` ` `  `    ``// To store if sub-tree is perfect or not ` `    ``boolean` `isPerfect; ` ` `  `    ``// Height of the tree ` `    ``int` `height; ` ` `  `    ``// Root of biggest perfect sub-tree ` `    ``node rootTree; ` `}; ` ` `  `// Function to return the biggest ` `// perfect binary sub-tree ` `static` `returnType findPerfectBinaryTree(node root) ` `{ ` ` `  `    ``// Declaring returnType that ` `    ``// needs to be returned ` `    ``returnType rt = ``new` `returnType(); ` ` `  `    ``// If root is null then it is considered as ` `    ``// perfect binary tree of height 0 ` `    ``if` `(root == ``null``) ` `    ``{ ` `        ``rt.isPerfect = ``true``; ` `        ``rt.height = ``0``; ` `        ``rt.rootTree = ``null``; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Recursive call for left and right child ` `    ``returnType lv = findPerfectBinaryTree(root.left); ` `    ``returnType rv = findPerfectBinaryTree(root.right); ` ` `  `    ``// If both left and right sub-trees are perfect and ` `    ``// there height is also same then sub-tree root ` `    ``// is also perfect binary subtree with height ` `    ``// plus one of its child sub-trees ` `    ``if` `(lv.isPerfect && rv.isPerfect &&  ` `        ``lv.height == rv.height) ` `    ``{ ` `        ``rt.height = lv.height + ``1``; ` `        ``rt.isPerfect = ``true``; ` `        ``rt.rootTree = root; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Else this sub-tree cannot be a perfect binary tree ` `    ``// and simply return the biggest sized perfect sub-tree ` `    ``// found till now in the left or right sub-trees ` `    ``rt.isPerfect = ``false``; ` `    ``rt.height = Math.max(lv.height, rv.height); ` `    ``rt.rootTree = (lv.height > rv.height ?  ` `                             ``lv.rootTree : rv.rootTree); ` `    ``return` `rt; ` `} ` ` `  `// Function to print the  ` `// inorder traversal of the tree ` `static` `void` `inorderPrint(node root) ` `{ ` `    ``if` `(root != ``null``) ` `    ``{ ` `        ``inorderPrint(root.left); ` `        ``System.out.print(root.data + ``" "``); ` `        ``inorderPrint(root.right); ` `    ``} ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args)  ` `{ ` `    ``// Create tree ` `    ``node root = newNode(``1``); ` `    ``root.left = newNode(``2``); ` `    ``root.right = newNode(``3``); ` `    ``root.left.left = newNode(``4``); ` `    ``root.left.right = newNode(``5``); ` `    ``root.right.left = newNode(``6``); ` ` `  `    ``// Get the biggest sizes perfect binary sub-tree ` `    ``returnType ans = findPerfectBinaryTree(root); ` ` `  `    ``// Height of the found sub-tree ` `    ``int` `h = ans.height; ` ` `  `    ``System.out.println(``"Size : "` `+  ` `                      ``(Math.pow(``2``, h) - ``1``)); ` ` `  `    ``// Print the inorder traversal of the found sub-tree ` `    ``System.out.print(``"Inorder Traversal : "``); ` `    ``inorderPrint(ans.rootTree); ` `} ` `}  ` ` `  `// This code is contributed by 29AjayKumar `

## Python3

 `# Python3 implementation of above approach ` ` `  `# Tree node  ` `class` `Node:  ` `    ``def` `__init__(``self``, data):  ` `        ``self``.data ``=` `data  ` `        ``self``.left ``=` `None` `        ``self``.right ``=` `None` ` `  `# To create a new node ` `def` `newNode(data): ` ` `  `    ``node ``=` `Node(``0``) ` `    ``node.data ``=` `data ` `    ``node.left ``=` `None` `    ``node.right ``=` `None` `    ``return` `node ` ` `  `# Structure for return type of ` `# function findPerfectBinaryTree ` `class` `returnType:  ` ` `  `    ``def` `__init__(``self``):  ` `         `  `        ``# To store if sub-tree is perfect or not ` `        ``isPerfect ``=` `0` ` `  `        ``# Height of the tree ` `        ``height ``=` `0` ` `  `        ``# Root of biggest perfect sub-tree ` `        ``rootTree ``=` `0` ` `  `# Function to return the biggest ` `# perfect binary sub-tree ` `def` `findPerfectBinaryTree(root): ` ` `  `    ``# Declaring returnType that ` `    ``# needs to be returned ` `    ``rt ``=` `returnType() ` ` `  `    ``# If root is None then it is considered as ` `    ``# perfect binary tree of height 0 ` `    ``if` `(root ``=``=` `None``) : ` `        ``rt.isPerfect ``=` `True` `        ``rt.height ``=` `0` `        ``rt.rootTree ``=` `None` `        ``return` `rt ` `     `  `    ``# Recursive call for left and right child ` `    ``lv ``=` `findPerfectBinaryTree(root.left) ` `    ``rv ``=` `findPerfectBinaryTree(root.right) ` ` `  `    ``# If both left and right sub-trees are perfect and ` `    ``# there height is also same then sub-tree root ` `    ``# is also perfect binary subtree with height ` `    ``# plus one of its child sub-trees ` `    ``if` `(lv.isPerfect ``and` `rv.isPerfect ``and`  `        ``lv.height ``=``=` `rv.height) : ` `        ``rt.height ``=` `lv.height ``+` `1` `        ``rt.isPerfect ``=` `True` `        ``rt.rootTree ``=` `root ` `        ``return` `rt ` `     `  `    ``# Else this sub-tree cannot be a perfect binary tree ` `    ``# and simply return the biggest sized perfect sub-tree ` `    ``# found till now in the left or right sub-trees ` `    ``rt.isPerfect ``=` `False` `    ``rt.height ``=` `max``(lv.height, rv.height) ` `    ``if` `(lv.height > rv.height ): ` `        ``rt.rootTree ``=` `lv.rootTree  ` `    ``else` `: ` `        ``rt.rootTree ``=` `rv.rootTree ` `    ``return` `rt ` ` `  `# Function to print the inorder traversal of the tree ` `def` `inorderPrint(root): ` ` `  `    ``if` `(root !``=` `None``) : ` `        ``inorderPrint(root.left) ` `        ``print` `(root.data, end ``=` `" "``) ` `        ``inorderPrint(root.right) ` `     `  `# Driver code ` ` `  `# Create tree ` `root ``=` `newNode(``1``) ` `root.left ``=` `newNode(``2``) ` `root.right ``=` `newNode(``3``) ` `root.left.left ``=` `newNode(``4``) ` `root.left.right ``=` `newNode(``5``) ` `root.right.left ``=` `newNode(``6``) ` ` `  `# Get the biggest sizes perfect binary sub-tree ` `ans ``=` `findPerfectBinaryTree(root) ` ` `  `# Height of the found sub-tree ` `h ``=` `ans.height ` ` `  `print` `(``"Size : "` `, ``pow``(``2``, h) ``-` `1``) ` ` `  `# Print the inorder traversal of the found sub-tree ` `print` `(``"Inorder Traversal : "``, end ``=` `" "``) ` `inorderPrint(ans.rootTree) ` ` `  `# This code is contributed by Arnab Kundu `

## C#

 `// C# implementation of the approach ` `using` `System; ` ` `  `class` `GFG  ` `{ ` `     `  `// Node structure of the tree ` `public` `class` `node ` `{ ` `    ``public` `int` `data; ` `    ``public` `node left; ` `    ``public` `node right; ` `}; ` ` `  `// To create a new node ` `static` `node newNode(``int` `data) ` `{ ` `    ``node node = ``new` `node(); ` `    ``node.data = data; ` `    ``node.left = ``null``; ` `    ``node.right = ``null``; ` `    ``return` `node; ` `} ` ` `  `// Structure for return type of ` `// function findPerfectBinaryTree ` `public` `class` `returnType  ` `{ ` ` `  `    ``// To store if sub-tree is perfect or not ` `    ``public` `bool` `isPerfect; ` ` `  `    ``// Height of the tree ` `    ``public` `int` `height; ` ` `  `    ``// Root of biggest perfect sub-tree ` `    ``public` `node rootTree; ` `}; ` ` `  `// Function to return the biggest ` `// perfect binary sub-tree ` `static` `returnType findPerfectBinaryTree(node root) ` `{ ` ` `  `    ``// Declaring returnType that ` `    ``// needs to be returned ` `    ``returnType rt = ``new` `returnType(); ` ` `  `    ``// If root is null then it is considered as ` `    ``// perfect binary tree of height 0 ` `    ``if` `(root == ``null``) ` `    ``{ ` `        ``rt.isPerfect = ``true``; ` `        ``rt.height = 0; ` `        ``rt.rootTree = ``null``; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Recursive call for left and right child ` `    ``returnType lv = findPerfectBinaryTree(root.left); ` `    ``returnType rv = findPerfectBinaryTree(root.right); ` ` `  `    ``// If both left and right sub-trees are perfect and ` `    ``// there height is also same then sub-tree root ` `    ``// is also perfect binary subtree with height ` `    ``// plus one of its child sub-trees ` `    ``if` `(lv.isPerfect && rv.isPerfect &&  ` `        ``lv.height == rv.height) ` `    ``{ ` `        ``rt.height = lv.height + 1; ` `        ``rt.isPerfect = ``true``; ` `        ``rt.rootTree = root; ` `        ``return` `rt; ` `    ``} ` ` `  `    ``// Else this sub-tree cannot be a perfect binary tree ` `    ``// and simply return the biggest sized perfect sub-tree ` `    ``// found till now in the left or right sub-trees ` `    ``rt.isPerfect = ``false``; ` `    ``rt.height = Math.Max(lv.height, rv.height); ` `    ``rt.rootTree = (lv.height > rv.height ?  ` `                             ``lv.rootTree : rv.rootTree); ` `    ``return` `rt; ` `} ` ` `  `// Function to print the  ` `// inorder traversal of the tree ` `static` `void` `inorderPrint(node root) ` `{ ` `    ``if` `(root != ``null``) ` `    ``{ ` `        ``inorderPrint(root.left); ` `        ``Console.Write(root.data + ``" "``); ` `        ``inorderPrint(root.right); ` `    ``} ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main(String[] args)  ` `{ ` `    ``// Create tree ` `    ``node root = newNode(1); ` `    ``root.left = newNode(2); ` `    ``root.right = newNode(3); ` `    ``root.left.left = newNode(4); ` `    ``root.left.right = newNode(5); ` `    ``root.right.left = newNode(6); ` ` `  `    ``// Get the biggest sizes perfect binary sub-tree ` `    ``returnType ans = findPerfectBinaryTree(root); ` ` `  `    ``// Height of the found sub-tree ` `    ``int` `h = ans.height; ` ` `  `    ``Console.WriteLine(``"Size : "` `+  ` `                     ``(Math.Pow(2, h) - 1)); ` ` `  `    ``// Print the inorder traversal of the found sub-tree ` `    ``Console.Write(``"Inorder Traversal : "``); ` `    ``inorderPrint(ans.rootTree); ` `} ` `} ` ` `  `// This code is contributed by Princi Singh `

Output:

```Size : 3
Inorder Traversal : 4 2 5
```

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.

Article Tags :
Practice Tags :

1

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.