Height = log(n + 1) - 1 where n is count of nodes.
Can be represented using an array, where the left child of a node at index i is stored at index 2i+1 and the right child is stored at index 2i+2. This makes it easy to access the children of a node and to traverse the tree.
Given a Binary Tree, the task is to check whether the given Binary Tree is a perfect Binary Tree or not.
Examples:Ā
Input: root[] = [7, 4, 9]
Output: true Explanation: As the root node 7 has two children and two leaf nodes 4 and 9 are at the same level.
Input: root[] = [7, 3, 8, 2, 5, N, 10, 1, N, N, N, N, N]
[Naive Method] Two Traversals - O(n) Time and O(h) Space
The idea is to first find the depth of the binary tree. Then recursively check whether all leaf nodes are present at the same depth and every internal node has exactly two children. If any node violates these conditions, the tree is not a perfect binary tree.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Function to find depth of treeintdepth(Node*root){if(root==nullptr)return0;return1+max(depth(root->left),depth(root->right));}// Recursive function to check perfect treeboolisPerfectRecur(Node*root,intd){// Empty tree is perfectif(root==nullptr)returntrue;// Leaf nodeif(root->left==nullptr&&root->right==nullptr)returnd==1;// If one child is missingif(root->left==nullptr||root->right==nullptr)returnfalse;// Recur for left and right subtreereturnisPerfectRecur(root->left,d-1)&&isPerfectRecur(root->right,d-1);}boolisPerfect(Node*root){// Find depthintd=depth(root);returnisPerfectRecur(root,d);}// Driver Codeintmain(){// Binary tree// 10// / \ // 20 30// / \ / \ // 40 50 60 70Node*root=newNode(10);root->left=newNode(20);root->right=newNode(30);root->left->left=newNode(40);root->left->right=newNode(50);root->right->left=newNode(60);root->right->right=newNode(70);if(isPerfect(root)){cout<<"True"<<endl;}else{cout<<"False"<<endl;}return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGfG{// Function to find depth of treestaticintdepth(Noderoot){if(root==null)return0;return1+Math.max(depth(root.left),depth(root.right));}// Recursive function to check perfect treestaticbooleanisPerfectRecur(Noderoot,intd){// Empty tree is perfectif(root==null)returntrue;// Leaf nodeif(root.left==null&&root.right==null)returnd==1;// If one child is missingif(root.left==null||root.right==null)returnfalse;// Recur for left and right subtreereturnisPerfectRecur(root.left,d-1)&&isPerfectRecur(root.right,d-1);}staticbooleanisPerfect(Noderoot){// Find depthintd=depth(root);returnisPerfectRecur(root,d);}// Driver Codepublicstaticvoidmain(String[]args){// Binary tree// 10// / \ // 20 30// / \ / \// 40 50 60 70Noderoot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(isPerfect(root)){System.out.println("True");}else{System.out.println("False");}}}
Python
classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to find depth of treedefdepth(root):ifrootisNone:return0return1+max(depth(root.left),depth(root.right))# Recursive function to check perfect treedefisPerfectRecur(root,d):# Empty tree is perfectifrootisNone:returnTrue# Leaf nodeifroot.leftisNoneandroot.rightisNone:returnd==1# If one child is missingifroot.leftisNoneorroot.rightisNone:returnFalse# Recur for left and right subtreereturnisPerfectRecur(root.left,d-1)andisPerfectRecur(root.right,d-1)defisPerfect(root):# Find depthd=depth(root)returnisPerfectRecur(root,d)# Driver Codeif__name__=='__main__':# Binary tree# 10# / \# 20 30# / \ / \# 40 50 60 70root=Node(10)root.left=Node(20)root.right=Node(30)root.left.left=Node(40)root.left.right=Node(50)root.right.left=Node(60)root.right.right=Node(70)ifisPerfect(root):print('True')else:print('False')
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to find depth of treestaticintdepth(Noderoot){if(root==null)return0;return1+Math.Max(depth(root.left),depth(root.right));}// Recursive function to check perfect treestaticboolisPerfectRecur(Noderoot,intd){// Empty tree is perfectif(root==null)returntrue;// Leaf nodeif(root.left==null&&root.right==null)returnd==1;// If one child is missingif(root.left==null||root.right==null)returnfalse;// Recur for left and right subtreereturnisPerfectRecur(root.left,d-1)&&isPerfectRecur(root.right,d-1);}staticboolisPerfect(Noderoot){// Find depthintd=depth(root);returnisPerfectRecur(root,d);}// Driver CodestaticvoidMain(){// Binary tree// 10// / \ // 20 30// / \ / \// 40 50 60 70Noderoot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(isPerfect(root)){Console.WriteLine("True");}else{Console.WriteLine("False");}}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to find depth of treefunctiondepth(root){if(root===null)return0;return1+Math.max(depth(root.left),depth(root.right));}// Recursive function to check perfect treefunctionisPerfectRecur(root,d){// Empty tree is perfectif(root===null)returntrue;// Leaf nodeif(root.left===null&&root.right===null)returnd===1;// If one child is missingif(root.left===null||root.right===null)returnfalse;// Recur for left and right subtreereturnisPerfectRecur(root.left,d-1)&&isPerfectRecur(root.right,d-1);}functionisPerfect(root){// Find depthconstd=depth(root);returnisPerfectRecur(root,d);}// Driver Code// Binary tree// 10// / \// 20 30// / \ / \// 40 50 60 70constroot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(isPerfect(root)){console.log('True');}else{console.log('False');}
Output
True
[Expected Approach] Single DFS Traversal - O(n) Time and O(h) Space
The idea is to recursively traverse the tree and store the level of the first leaf node. Then, check whether all other leaf nodes are at the same level and every non-leaf node has exactly two children. If both conditions are satisfied, the tree is a perfect binary tree.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Recursive function to check perfect binary treeboolsolve(Node*root,intlevel,int&leafLevel){// Empty tree is perfectif(root==nullptr)returntrue;// If leaf nodeif(root->left==nullptr&&root->right==nullptr){// Store level of first leaf nodeif(leafLevel==-1)leafLevel=level;// All leaf nodes must be at same levelreturnlevel==leafLevel;}// If one child is missingif(root->left==nullptr||root->right==nullptr){returnfalse;}// Recur for left and right subtreereturnsolve(root->left,level+1,leafLevel)&&solve(root->right,level+1,leafLevel);}// Function to check whether binary tree is perfectboolisPerfect(Node*root){// Stores level of first leaf nodeintleafLevel=-1;returnsolve(root,0,leafLevel);}// Driver Codeintmain(){// Binary tree// 10// / \ // 20 30// / \ / \ // 40 50 60 70Node*root=newNode(10);root->left=newNode(20);root->right=newNode(30);root->left->left=newNode(40);root->left->right=newNode(50);root->right->left=newNode(60);root->right->right=newNode(70);if(isPerfect(root)){cout<<"True"<<endl;}else{cout<<"False"<<endl;}return0;}
Java
/* * Recursive function to check perfect binary tree */classNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;this.left=this.right=null;}}publicclassGfG{privatestaticintleafLevel=-1;privatestaticbooleansolve(Noderoot,intlevel){// Empty tree is perfectif(root==null)returntrue;// If leaf nodeif(root.left==null&&root.right==null){// Store level of first leaf nodeif(leafLevel==-1)leafLevel=level;// All leaf nodes must be at same levelreturnlevel==leafLevel;}// If one child is missingif(root.left==null||root.right==null)returnfalse;// Recur for left and right subtreereturnsolve(root.left,level+1)&&solve(root.right,level+1);}publicstaticbooleanisPerfect(Noderoot){// Stores level of first leaf nodeleafLevel=-1;returnsolve(root,0);}publicstaticvoidmain(String[]args){// Binary tree// 10// / \// 20 30// / \ / \// 40 50 60 70Noderoot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(isPerfect(root))System.out.println("True");elseSystem.out.println("False");}}
Python
classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Recursive function to check perfect binary treedefsolve(root,level,leafLevel):# Empty tree is perfectifrootisNone:returnTrue# If leaf nodeifroot.leftisNoneandroot.rightisNone:# Store level of first leaf nodeifleafLevel[0]==-1:leafLevel[0]=level# All leaf nodes must be at same levelreturnlevel==leafLevel[0]# If one child is missingifroot.leftisNoneorroot.rightisNone:returnFalse# Recur for left and right subtreereturnsolve(root.left,level+1,leafLevel)andsolve(root.right,level+1,leafLevel)# Function to check whether binary tree is perfectdefisPerfect(root):# Stores level of first leaf nodeleafLevel=[-1]returnsolve(root,0,leafLevel)# Driver Codeif__name__=='__main__':# Binary tree# 10# / \# 20 30# / \ / \# 40 50 60 70root=Node(10)root.left=Node(20)root.right=Node(30)root.left.left=Node(40)root.left.right=Node(50)root.right.left=Node(60)root.right.right=Node(70)ifisPerfect(root):print('True')else:print('False')
C#
usingSystem;publicclassNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;this.left=this.right=null;}}publicclassGfG{privatestaticintleafLevel=-1;privatestaticboolSolve(Noderoot,intlevel){// Empty tree is perfectif(root==null)returntrue;// If leaf nodeif(root.left==null&&root.right==null){// Store level of first leaf nodeif(leafLevel==-1)leafLevel=level;// All leaf nodes must be at same levelreturnlevel==leafLevel;}// If one child is missingif(root.left==null||root.right==null)returnfalse;// Recur for left and right subtreereturnSolve(root.left,level+1)&&Solve(root.right,level+1);}publicstaticboolIsPerfect(Noderoot){// Stores level of first leaf nodeleafLevel=-1;returnSolve(root,0);}publicstaticvoidMain(string[]args){// Binary tree// 10// / \// 20 30// / \ / \// 40 50 60 70Noderoot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(IsPerfect(root))Console.WriteLine("True");elseConsole.WriteLine("False");}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Recursive function to check perfect binary treefunctionsolve(root,level,leafLevel){// Empty tree is perfectif(root===null)returntrue;// If leaf nodeif(root.left===null&&root.right===null){// Store level of first leaf nodeif(leafLevel[0]===-1)leafLevel[0]=level;// All leaf nodes must be at same levelreturnlevel===leafLevel[0];}// If one child is missingif(root.left===null||root.right===null)returnfalse;// Recur for left and right subtreereturnsolve(root.left,level+1,leafLevel)&&solve(root.right,level+1,leafLevel);}// Function to check whether binary tree is perfectfunctionisPerfect(root){// Stores level of first leaf nodeletleafLevel=[-1];returnsolve(root,0,leafLevel);}// Driver Code// Binary tree// 10// / \// 20 30// / \ / \// 40 50 60 70letroot=newNode(10);root.left=newNode(20);root.right=newNode(30);root.left.left=newNode(40);root.left.right=newNode(50);root.right.left=newNode(60);root.right.right=newNode(70);if(isPerfect(root))console.log('True');elseconsole.log('False');