Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Check whether a given binary tree is perfect or not

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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.

Below is an idea to check whether a given Binary Tree is perfect or not.  

  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’

Implementation:

C++




// 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




// 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




# 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#




// 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*/

Javascript




<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:

  • Time complexity: O(n) 
  • Space Complexity: O(n)

Method 2: 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.

Implementation:

C++




// 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

Java




/*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




# 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#




// 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)

Javascript




<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:

  • Time Complexity: O(n)
  • Space Complexity:O(n)

This article is contributed by Nikhil Papisetty. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 


My Personal Notes arrow_drop_up
Last Updated : 27 Apr, 2023
Like Article
Save Article
Similar Reads
Related Tutorials