Open In App

Check whether a given binary tree is perfect or not

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

Recommended Practice

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:  

  1. Find depth of any node (in below tree we find depth of leftmost node). Let this depth be d.
  2. 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>

Output
Yes









Complexity Analysis:

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.");
}

Output
The binary tree is perfect.

Complexity Analysis:

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>

Output
Yes









Complexity Analysis:

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");
    }
})();

Output
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).

 


Article Tags :