Given a Binary Tree, write a function to check whether the given Binary Tree is a perfect Binary Tree or not.
A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at same level.
Examples:
The following tree is a perfect binary tree
10
/ \
20 30
/ \ / \
40 50 60 70
18
/ \
15 30
The following tree is not a perfect binary tree
1
/ \
2 3
\ / \
4 5 6
A Perfect Binary Tree of height h (where height is number of nodes on path from root to leaf) has 2h – 1 nodes.
Solution Approach:
Method 1:
- Find depth of any node (in below tree we find depth of leftmost node). Let this depth be d.
-
Now recursively traverse the tree and check for following two conditions.
- Every internal node should have both children non-empty
- All leaves are at depth ‘d’
Below is the implementation:
// C++ program to check whether a given // Binary Tree is Perfect or not #include<bits/stdc++.h> /* Tree node structure */ struct Node
{ int key;
struct Node *left, *right;
}; // Returns depth of leftmost leaf. int findADepth(Node *node)
{ int d = 0;
while (node != NULL)
{
d++;
node = node->left;
}
return d;
} /* This function tests if a binary tree is perfect or not. It basically checks for two things :
1) All leaves are at same level
2) All internal nodes have two children */
bool isPerfectRec( struct Node* root, int d, int level = 0)
{ // An empty tree is perfect
if (root == NULL)
return true ;
// If leaf node, then its depth must be same as
// depth of all other leaves.
if (root->left == NULL && root->right == NULL)
return (d == level+1);
// If internal node and one child is empty
if (root->left == NULL || root->right == NULL)
return false ;
// Left and right subtrees must be perfect.
return isPerfectRec(root->left, d, level+1) &&
isPerfectRec(root->right, d, level+1);
} // Wrapper over isPerfectRec() bool isPerfect(Node *root)
{ int d = findADepth(root);
return isPerfectRec(root, d);
} /* Helper function that allocates a new node with the given key and NULL left and right pointer. */
struct Node *newNode( int k)
{ struct Node *node = new Node;
node->key = k;
node->right = node->left = NULL;
return node;
} // Driver Program int main()
{ struct Node* root = NULL;
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))
printf ( "Yes\n" );
else
printf ( "No\n" );
return (0);
} |
// Java program to check whether a given // Binary Tree is Perfect or not class GfG {
/* Tree node structure */ static class Node
{ int key;
Node left, right;
} // Returns depth of leftmost leaf. static int findADepth(Node node)
{ int d = 0 ;
while (node != null )
{ d++;
node = node.left;
} return d;
} /* This function tests if a binary tree is perfect or not. It basically checks for two things : 1) All leaves are at same level 2) All internal nodes have two children */ static boolean isPerfectRec(Node root, int d, int level)
{ // An empty tree is perfect
if (root == null )
return true ;
// If leaf node, then its depth must be same as
// depth of all other leaves.
if (root.left == null && root.right == null )
return (d == level+ 1 );
// If internal node and one child is empty
if (root.left == null || root.right == null )
return false ;
// Left and right subtrees must be perfect.
return isPerfectRec(root.left, d, level+ 1 ) && isPerfectRec(root.right, d, level+ 1 );
} // Wrapper over isPerfectRec() static boolean isPerfect(Node root)
{ int d = findADepth(root);
return isPerfectRec(root, d, 0 );
} /* Helper function that allocates a new node with the given key and NULL left and right pointer. */ static Node newNode( int k)
{ Node node = new Node();
node.key = k;
node.right = null ;
node.left = null ;
return node;
} // Driver Program public static void main(String args[])
{ Node root = null ;
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) == true )
System.out.println( "Yes" );
else
System.out.println( "No" );
} } |
# Python3 program to check whether a # given Binary Tree is Perfect or not # Helper class that allocates a new # node with the given key and None # left and right pointer. class newNode:
def __init__( self , k):
self .key = k
self .right = self .left = None
# Returns depth of leftmost leaf. def findADepth(node):
d = 0
while (node ! = None ):
d + = 1
node = node.left
return d
# This function tests if a binary tree # is perfect or not. It basically checks # for two things : # 1) All leaves are at same level # 2) All internal nodes have two children def isPerfectRec(root, d, level = 0 ):
# An empty tree is perfect
if (root = = None ):
return True
# If leaf node, then its depth must
# be same as depth of all other leaves.
if (root.left = = None and root.right = = None ):
return (d = = level + 1 )
# If internal node and one child is empty
if (root.left = = None or root.right = = None ):
return False
# Left and right subtrees must be perfect.
return (isPerfectRec(root.left, d, level + 1 ) and
isPerfectRec(root.right, d, level + 1 ))
# Wrapper over isPerfectRec() def isPerfect(root):
d = findADepth(root)
return isPerfectRec(root, d)
# Driver Code if __name__ = = '__main__' :
root = None
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)):
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by pranchalK |
// C# program to check whether a given // Binary Tree is Perfect or not using System;
class GfG
{ /* Tree node structure */ class Node
{ public int key;
public Node left, right;
} // Returns depth of leftmost leaf. static int findADepth(Node node)
{ int d = 0;
while (node != null )
{
d++;
node = node.left;
}
return d;
} /* This function tests if a binary tree is perfect or not. It basically checks for two things : 1) All leaves are at same level 2) All internal nodes have two children */ static bool isPerfectRec(Node root,
int d, int level)
{ // An empty tree is perfect
if (root == null )
return true ;
// If leaf node, then its depth must be same as
// depth of all other leaves.
if (root.left == null && root.right == null )
return (d == level+1);
// If internal node and one child is empty
if (root.left == null || root.right == null )
return false ;
// Left and right subtrees must be perfect.
return isPerfectRec(root.left, d, level+1) &&
isPerfectRec(root.right, d, level+1);
} // Wrapper over isPerfectRec() static bool isPerfect(Node root)
{ int d = findADepth(root);
return isPerfectRec(root, d, 0);
} /* Helper function that allocates a new node with the given key and NULL left and right pointer. */ static Node newNode( int k)
{ Node node = new Node();
node.key = k;
node.right = null ;
node.left = null ;
return node;
} // Driver code public static void Main()
{ Node root = null ;
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) == true )
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
} } /* This code is contributed by Rajput-Ji*/ |
<script> // Javascript program to check whether a given // Binary Tree is Perfect or not /* Tree node structure */ class Node { constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
} // Returns depth of leftmost leaf. function findADepth(node)
{ var d = 0;
while (node != null )
{
d++;
node = node.left;
}
return d;
} /* This function tests if a binary tree is perfect or not. It basically checks for two things : 1) All leaves are at same level 2) All internal nodes have two children */ function isPerfectRec(root, d, level)
{ // An empty tree is perfect
if (root == null )
return true ;
// If leaf node, then its depth must be same as
// depth of all other leaves.
if (root.left == null && root.right == null )
return (d == level + 1);
// If internal node and one child is empty
if (root.left == null || root.right == null )
return false ;
// Left and right subtrees must be perfect.
return isPerfectRec(root.left, d, level + 1) &&
isPerfectRec(root.right, d, level + 1);
} // Wrapper over isPerfectRec() function isPerfect(root)
{ var d = findADepth(root);
return isPerfectRec(root, d, 0);
} /* Helper function that allocates a new node with the given key and NULL left and right pointer. */ function newNode(k)
{ var node = new Node();
node.key = k;
node.right = null ;
node.left = null ;
return node;
} // Driver code var root = null ;
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) == true )
document.write( "Yes" );
else document.write( "No" );
// This code is contributed by noob2000 </script> |
Yes
Complexity Analysis:
- Time complexity: O(n)
- Space Complexity: O(n)
Method 2: Using Recursion
Since a full binary tree has 2^h – 1 nodes, we can count the number of nodes in the binary tree and determine whether it is a power of 2 or not. Also, the number of nodes (n) should be equal to 2^h – 1.
//Flow of recursion
1. if either left or right child is missing, tree is imperfect return false.
2. If both children are missing (leaf node), return true.
3. if either the left/right children of the left subtree or the left/right children of the right subtree is missing , means leaves aren’t at same level so tree is imperfect hence return false.
3. If either left or right subtree is not perfect, return false.
4. else If all conditions pass, the tree is perfect.
Below is the implementation:
#include <iostream> // Helper class to create a node of a binary tree class Node {
public :
int data;
Node* left;
Node* right;
Node( int data) {
this ->data = data;
this ->left = this ->right = nullptr;
}
}; bool isPerfect(Node* root) {
if ((root->left == nullptr) != (root->right == nullptr))
return false ;
if (root->left == nullptr)
return true ;
if ((root->left->left == nullptr) != (root->right->left == nullptr))
return false ;
if (!isPerfect(root->left) || !isPerfect(root->right))
return false ;
return true ;
} int main() {
// Create a sample binary tree
Node* root = new Node(10);
root->left = new Node(20);
root->right = new Node(30);
root->left->left = new Node(40);
root->left->right = new Node(50);
root->right->left = new Node(60);
root->right->right = new Node(70);
// Check if the binary tree is perfect
bool isPerfectTree = isPerfect(root);
if (isPerfectTree) {
std::cout << "The binary tree is perfect." << std::endl;
} else {
std::cout << "The binary tree is not perfect." << std::endl;
}
return 0;
} |
/*package whatever //do not write package name here */ import java.io.*;
// helper class to create node of binary tree class Node {
int data;
Node left, right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
} public class GFG {
public static boolean isPerfect(Node root)
{
// NOTE: XOR operator(^) returns true is anyone of
// the condition is true
if (root.left == null ^ root.right == null )
return false ;
if (root.left == null )
return true ;
if (root.left.left == null
^ root.right.left == null )
return false ;
if (!isPerfect(root.left) || !isPerfect(root.right))
return false ;
else
return true ;
}
public static void main(String[] args)
{
// Create a sample binary tree
Node root = new Node( 10 );
root.left = new Node( 20 );
root.right = new Node( 30 );
root.left.left = new Node( 40 );
root.left.right = new Node( 50 );
root.right.left = new Node( 60 );
root.right.right = new Node( 70 );
// Check if the binary tree is perfect
boolean isPerfectTree = isPerfect(root);
if (isPerfectTree) {
System.out.println(
"The binary tree is perfect." );
}
else {
System.out.println(
"The binary tree is not perfect." );
}
}
} //this code has been contributed by Nishant Jain |
# Helper class to create a node of a binary tree class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def isPerfect(root):
if (root.left is None ) ! = (root.right is None ):
return False
if root.left is None :
return True
if (root.left.left is None ) ! = (root.right.left is None ):
return False
if not isPerfect(root.left) or not isPerfect(root.right):
return False
return True
# Create a sample binary tree root = 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 )
# Check if the binary tree is perfect isPerfectTree = isPerfect(root)
if isPerfectTree:
print ( "The binary tree is perfect." )
else :
print ( "The binary tree is not perfect." )
|
using System;
// Helper class to create a node of a binary tree class Node
{ public int data;
public Node left;
public Node right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
} class Program
{ static bool IsPerfect(Node root)
{
if ((root.left == null ) != (root.right == null ))
return false ;
if (root.left == null )
return true ;
if ((root.left.left == null ) != (root.right.left == null ))
return false ;
if (!IsPerfect(root.left) || !IsPerfect(root.right))
return false ;
return true ;
}
static void Main( string [] args)
{
// Create a sample binary tree
Node root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.left = new Node(60);
root.right.right = new Node(70);
// Check if the binary tree is perfect
bool isPerfectTree = IsPerfect(root);
if (isPerfectTree)
{
Console.WriteLine( "The binary tree is perfect." );
}
else
{
Console.WriteLine( "The binary tree is not perfect." );
}
}
} |
//helper class to create the node of a binary tree class Node { constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
} function isPerfect(root) {
if ((root.left === null ) !== (root.right === null ))
return false ;
if (root.left === null )
return true ;
if ((root.left.left === null ) !== (root.right.left === null ))
return false ;
if (!isPerfect(root.left) || !isPerfect(root.right))
return false ;
return true ;
} // Create a sample binary tree const root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.left = new Node(60);
root.right.right = new Node(70);
// Check if the binary tree is perfect const isPerfectTree = isPerfect(root); if (isPerfectTree) {
console.log( "The binary tree is perfect." );
} else {
console.log( "The binary tree is not perfect." );
} |
The binary tree is perfect.
Complexity Analysis:
- Time complexity: O(n) , because each node is traversed only once
- Space Complexity: O(n) , because of recursion stack
Method 3: Using the length of the binary tree
Since a full binary tree has 2^h – 1 nodes, we can count the number of nodes in the binary tree and determine whether it is a power of 2 or not. Also, the number of nodes (n) should be equal to 2^h – 1.
Below is the implementation:
// C++ program to check whether a // given Binary Tree is Perfect or not #include <bits/stdc++.h> using namespace std;
// Helper class that allocates a new node with // the given key and None left and right pointer. class newNode{
public :
int key;
newNode*right,*left;
newNode( int k){
this ->key = k;
this ->right = this ->left = NULL;
}
}; // This functions gets the size of binary tree // Basically, the number of nodes this binary tree has int getLength(newNode* root){
if (root == NULL)
return 0;
return 1 + getLength(root->left) + getLength(root->right);
} // Returns True if length of binary tree is a power of 2 else False bool isPerfect(newNode* root){
int length = getLength(root);
return (length & (length+1)) == 0;
} int main()
{ newNode* root = new newNode(10);
root->left = new newNode(20);
root->right = new newNode(30);
root->left->left = new newNode(40);
root->left->right = new newNode(50);
root->right->left = new newNode(60);
root->right->right = new newNode(70);
if (isPerfect(root))
cout<< "Yes" <<endl;
else
cout<< "No" <<endl;
} // This code is contributed by Yash Agarwal |
/*package whatever //do not write package name here */ import java.io.*;
class GFG
{ // Java program to check whether a // given Binary Tree is Perfect or not // Helper class that allocates a new // node with the given key and None // left and right pointer. static class newNode{
public int key;
public newNode right,left;
public newNode( int k){
this .key = k;
this .right = this .left = null ;
}
}; //Returns height of tree static int getHeight(newNode root) {
if (root == null ) return 0 ;
else if (root.left == null && root.right == null ) return 1 ; //height of leaf node is 1
int lHeight = height(root.left); //height of left subtree
int rHeight = height(root.right); //height of right subtree
return 1 + Math.max(lHeight, rHeight);
} // This functions gets the size of binary tree // Basically, the number of nodes this binary tree has static int getLength(newNode root){
if (root == null )
return 0 ;
return 1 + getLength(root.left) + getLength(root.right);
} // Returns True if length of binary tree is 2^h - 1 static boolean isPerfect(newNode root){
int length = getLength(root);
int height = getHeight(root);
return length + 1 == ( int )Math.pow( 2 , height);
} /* Driver program to test above function*/ public static void main(String args[])
{ newNode root = new newNode( 10 );
root.left = new newNode( 20 );
root.right = new newNode( 30 );
root.left.left = new newNode( 40 );
root.left.right = new newNode( 50 );
root.right.left = new newNode( 60 );
root.right.right = new newNode( 70 );
if (isPerfect(root))
System.out.println( "Yes" );
else
System.out.println( "No" );
} } // This code is contributed by shinjanpatra |
# Python3 program to check whether a # given Binary Tree is Perfect or not # Helper class that allocates a new # node with the given key and None # left and right pointer. class newNode:
def __init__( self , k):
self .key = k
self .right = self .left = None
#This functions gets the size of binary tree #Basically, the number of nodes this binary tree has def getLength(root):
if root = = None :
return 0
return 1 + getLength(root.left) + getLength(root.right)
#Returns True if length of binary tree is a power of 2 else False def isPerfect(root):
length = getLength(root)
return length & (length + 1 ) = = 0
# Driver Code if __name__ = = '__main__' :
root = None
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)):
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by beardedowl |
// C# program to check whether a given // Binary Tree is Perfect or not using System;
class GfG{
// Helper class that allocates a new node with
// the given key and None left and right pointer.
class newNode
{
public int key;
public newNode left, right;
public newNode( int k){
key = k;
right = left = null ;
}
}
// This functions gets the size of binary tree
// Basically, the number of nodes this binary tree has
static int getLength(newNode root){
if (root == null ) return 0;
return 1 + getLength(root.left) + getLength(root.right);
}
// Returns True if length of binary tree is a power of 2 else False
static bool isPerfect(newNode root){
int length = getLength(root);
return (length & (length+1)) == 0;
}
public static void Main(){
newNode root = null ;
root = new newNode(10);
root.left = new newNode(20);
root.right = new newNode(30);
root.left.left = new newNode(40);
root.left.right = new newNode(50);
root.right.left = new newNode(60);
root.right.left.left = new newNode(70);
if (isPerfect(root) == true )
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
} // THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002) |
<script> // JavaScript program to check whether a // given Binary Tree is Perfect or not // Helper class that allocates a new // node with the given key and None // left and right pointer. class newNode{ constructor(k){
this .key = k
this .right = this .left = null
}
} // This functions gets the size of binary tree // Basically, the number of nodes this binary tree has function getLength(root){
if (root == null )
return 0
return 1 + getLength(root.left) + getLength(root.right)
} // Returns True if length of binary tree is a power of 2 else False function isPerfect(root){
let length = getLength(root)
return length & (length+1) == 0
} // Driver Code let root = null
root = new newNode(10)
root.left = new newNode(20)
root.right = new newNode(30)
root.left.left = new newNode(40)
root.left.right = new newNode(50)
root.right.left = new newNode(60)
root.right.right = new newNode(70)
if (isPerfect(root))
document.write( "Yes" )
else document.write( "No" )
// This code is contributed by shinjanpatra </script> |
Yes
Complexity Analysis:
- Time Complexity: O(n)
- Space Complexity:O(n)
Method 4: Using level order traversal:
The idea is to perform a level-order traversal of the binary tree using a queue. By traversing the tree level by level, we can check if the tree satisfies the conditions of a perfect binary tree.
Below is the implementation:
// C++ code to implement the level order traversal approach #include <iostream> #include <queue> #include <vector> using namespace std;
// Structure for a binary tree node struct Node {
int data;
Node* left;
Node* right;
}; // Function to check if the given binary tree is a perfect // binary tree bool isPerfectBinaryTree(Node* root)
{ if (root == nullptr) {
return true ;
}
queue<Node*> q;
q.push(root);
int level = 1; // Current level of the tree
int flag
= 1; // Flag to track if the tree is perfect or not
while (!q.empty()) {
int size = q.size();
vector< int > levelValues;
// Traverse all nodes at the current level
for ( int i = 0; i < size; i++) {
Node* temp = q.front();
q.pop();
levelValues.push_back(temp->data);
// Enqueue the left and right children of the
// current node
if (temp->left) {
q.push(temp->left);
}
if (temp->right) {
q.push(temp->right);
}
}
// Check if the number of nodes at the current level
// is not zero and not equal to the expected level
// size
if (levelValues.size() != 0
&& levelValues.size() != level) {
flag = 0; // Tree is not perfect
}
// Update the expected level size for the next level
level = level * 2;
}
return flag;
} // Helper function to create a new node Node* createNode( int data)
{ Node* newNode = new Node();
if (newNode) {
newNode->data = data;
newNode->left = newNode->right = nullptr;
}
return newNode;
} // Driver code int main()
{ // Create a binary tree
Node* root = createNode(7);
root->left = createNode(4);
root->right = createNode(9);
// Check if the binary tree is perfect
bool isPerfect = isPerfectBinaryTree(root);
if (isPerfect) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
return 0;
} // This code is contributed by Veerendra_Singh_Rajpoot |
import java.util.LinkedList;
import java.util.Queue;
import java.util.Vector;
class Node {
int data;
Node left;
Node right;
Node( int data) {
this .data = data;
left = right = null ;
}
} class Main {
// Function to check if the given binary tree is a perfect
// binary tree
static boolean isPerfectBinaryTree(Node root) {
if (root == null ) {
return true ;
}
Queue<Node> q = new LinkedList<>();
q.add(root);
int level = 1 ; // Current level of the tree
int flag = 1 ; // Flag to track if the tree is perfect or not
while (!q.isEmpty()) {
int size = q.size();
Vector<Integer> levelValues = new Vector<>();
// Traverse all nodes at the current level
for ( int i = 0 ; i < size; i++) {
Node temp = q.poll();
levelValues.add(temp.data);
// Enqueue the left and right children of the current node
if (temp.left != null ) {
q.add(temp.left);
}
if (temp.right != null ) {
q.add(temp.right);
}
}
// Check if the number of nodes at the current level
// is not zero and not equal to the expected level size
if (levelValues.size() != 0 && levelValues.size() != level) {
flag = 0 ; // Tree is not perfect
}
// Update the expected level size for the next level
level = level * 2 ;
}
return flag == 1 ;
}
// Driver code
public static void main(String[] args) {
// Create a binary tree
Node root = new Node( 7 );
root.left = new Node( 4 );
root.right = new Node( 9 );
// Check if the binary tree is perfect
boolean isPerfect = isPerfectBinaryTree(root);
if (isPerfect) {
System.out.println( "Yes" );
} else {
System.out.println( "No" );
}
}
} // This code is contributed by Veerendra_Singh_Rajpoot |
from queue import Queue
# Structure for a binary tree node class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
# Function to check if the given binary tree is a perfect binary tree def isPerfectBinaryTree(root):
if root is None :
return True
q = Queue()
q.put(root)
level = 1 # Current level of the tree
flag = 1 # Flag to track if the tree is perfect or not
while not q.empty():
size = q.qsize()
level_values = []
# Traverse all nodes at the current level
for i in range (size):
temp = q.get()
level_values.append(temp.data)
# Enqueue the left and right children of the current node
if temp.left:
q.put(temp.left)
if temp.right:
q.put(temp.right)
# Check if the number of nodes at the current level
# is not zero and not equal to the expected level size
if len (level_values) ! = 0 and len (level_values) ! = level:
flag = 0 # Tree is not perfect
# Update the expected level size for the next level
level * = 2
return flag
# Helper function to create a new node def createNode(data):
new_node = Node(data)
return new_node
# Driver code if __name__ = = "__main__" :
# Create a binary tree
root = createNode( 7 )
root.left = createNode( 4 )
root.right = createNode( 9 )
# Check if the binary tree is perfect
is_perfect = isPerfectBinaryTree(root)
if is_perfect:
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by shivamgupta0987654321 |
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left;
public Node right;
} public class PerfectBinaryTreeChecker {
public static bool IsPerfectBinaryTree(Node root)
{
if (root == null ) {
return true ;
}
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
int level = 1; // Current level of the tree
int flag = 1; // Flag to track if the tree is
// perfect or not
while (q.Count > 0) {
int size = q.Count;
List< int > levelValues = new List< int >();
// Traverse all nodes at the current level
for ( int i = 0; i < size; i++) {
Node temp = q.Dequeue();
levelValues.Add(temp.data);
// Enqueue the left and right children of
// the current node
if (temp.left != null ) {
q.Enqueue(temp.left);
}
if (temp.right != null ) {
q.Enqueue(temp.right);
}
}
// Check if the number of nodes at the current
// level is not zero and not equal to the
// expected level size
if (levelValues.Count != 0
&& levelValues.Count != level) {
flag = 0; // Tree is not perfect
}
// Update the expected level size for the next
// level
level = level * 2;
}
return flag == 1;
}
public static Node CreateNode( int data)
{
Node newNode = new Node();
if (newNode != null ) {
newNode.data = data;
newNode.left = newNode.right = null ;
}
return newNode;
}
public static void Main( string [] args)
{
// Create a binary tree
Node root = CreateNode(7);
root.left = CreateNode(4);
root.right = CreateNode(9);
// Check if the binary tree is perfect
bool isPerfect = IsPerfectBinaryTree(root);
if (isPerfect) {
Console.WriteLine( "Yes" );
}
else {
Console.WriteLine( "No" );
}
}
} // This code is contributed by akshitaguprzj3 |
// Structure for a binary tree node class Node { constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
} // Function to check if the given // binary tree is a perfect binary tree function isPerfectBinaryTree(root) {
if (!root) {
return true ;
}
let queue = [root];
let level = 1; // Current level of the tree
let flag = 1; // Flag to track if the tree is perfect or not
while (queue.length > 0) {
const size = queue.length;
const levelValues = [];
// Traverse all nodes at the current level
for (let i = 0; i < size; i++) {
const temp = queue.shift();
levelValues.push(temp.data);
// Enqueue the left and right children of the current node
if (temp.left) {
queue.push(temp.left);
}
if (temp.right) {
queue.push(temp.right);
}
}
if (levelValues.length !== 0 && levelValues.length !== level) {
flag = 0; // Tree is not perfect
}
// Update the expected level size for the next level
level *= 2;
}
return flag === 1;
} // Helper function to create a new node function createNode(data) {
return new Node(data);
} // Driver code ( function main() {
// Create a binary tree
const root = createNode(7);
root.left = createNode(4);
root.right = createNode(9);
// Check if the binary tree is perfect
const isPerfect = isPerfectBinaryTree(root);
if (isPerfect) {
console.log( "Yes" );
} else {
console.log( "No" );
}
})(); |
Yes
Time Complexity: O(N), O(N), where N is the number of nodes in the binary tree. This is because we perform a level-order traversal of the tree using a queue, visiting each node once.
Auxiliary Space: O(N), O(M), where M is the maximum number of nodes at any level in the binary tree. In the worst case, a perfect binary tree will have N/2 nodes at the last level, resulting in M = N/2. Hence, the space complexity can be simplified to O(N).