Perfect Binary Tree

Last Updated : 20 May, 2026

A perfect binary tree is a type of binary tree that is completely filled at every level with no missing nodes.

  • All internal nodes have degree 2 and all leaf nodes are at the same level.
  • Number of leaf nodes = 2h where h is height of the binary tree.
  • Number of internal nodes = Leaf nodes - 1 = 2h - 1
  • Total Nodes = Leaf Nodes + Non-leaf nodes + 1 = 2h + 1 - 1
  • 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]

blobid0_1778757069

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]

blobid3_1778757183

Output: false

Try It Yourself
redirect icon

[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>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;

    Node(int x)
    {
        data = x;
        left = right = nullptr;
    }
};

// Function to find depth of tree
int depth(Node *root)
{
    if (root == nullptr)
        return 0;

    return 1 + max(depth(root->left), depth(root->right));
}

// Recursive function to check perfect tree
bool isPerfectRecur(Node *root, int d)
{

    // Empty tree is perfect
    if (root == nullptr)
        return true;

    // Leaf node
    if (root->left == nullptr && root->right == nullptr)
        return d == 1;

    // If one child is missing
    if (root->left == nullptr || root->right == nullptr)
        return false;

    // Recur for left and right subtree
    return isPerfectRecur(root->left, d - 1) && isPerfectRecur(root->right, d - 1);
}

bool isPerfect(Node *root)
{
    // Find depth
    int d = depth(root);

    return isPerfectRecur(root, d);
}

// Driver Code
int main()
{

    // Binary tree
    //           10
    //        /     \  
    //      20       30
    //     /  \     /  \
    //   40    50  60   70
    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);

    if (isPerfect(root))
    {
        cout << "True" << endl;
    }
    else
    {
        cout << "False" << endl;
    }
    return 0;
}
Java
import java.util.*;

class Node {
    int data;
    Node left;
    Node right;

    Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GfG {
    // Function to find depth of tree
    static int depth(Node root)
    {
        if (root == null)
            return 0;

        return 1
            + Math.max(depth(root.left), depth(root.right));
    }

    // Recursive function to check perfect tree
    static boolean isPerfectRecur(Node root, int d)
    {
        // Empty tree is perfect
        if (root == null)
            return true;

        // Leaf node
        if (root.left == null && root.right == null)
            return d == 1;

        // If one child is missing
        if (root.left == null || root.right == null)
            return false;

        // Recur for left and right subtree
        return isPerfectRecur(root.left, d - 1)
            && isPerfectRecur(root.right, d - 1);
    }

    static boolean isPerfect(Node root)
    {
        // Find depth
        int d = depth(root);

        return isPerfectRecur(root, d);
    }

    // Driver Code
    public static void main(String[] args)
    {
        // Binary tree
        //           10
        //        /     \  
        //      20       30
        //     /  \     /  \
        //   40    50  60   70
        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);

        if (isPerfect(root)) {
            System.out.println("True");
        }
        else {
            System.out.println("False");
        }
    }
}
Python
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# Function to find depth of tree
def depth(root):
    if root is None:
        return 0

    return 1 + max(depth(root.left), depth(root.right))

# Recursive function to check perfect tree
def isPerfectRecur(root, d):
    # Empty tree is perfect
    if root is None:
        return True

    # Leaf node
    if root.left is None and root.right is None:
        return d == 1

    # If one child is missing
    if root.left is None or root.right is None:
        return False

    # Recur for left and right subtree
    return isPerfectRecur(root.left, d - 1) and isPerfectRecur(root.right, d - 1)

def isPerfect(root):
    # Find depth
    d = depth(root)

    return isPerfectRecur(root, d)

# Driver Code
if __name__ == '__main__':
    # Binary tree
    #           10
    #        /     \
    #      20       30
    #     /  \     /  \
    #   40    50  60   70
    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)

    if isPerfect(root):
        print('True')
    else:
        print('False')
C#
using System;

class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GfG {
    // Function to find depth of tree
    static int depth(Node root)
    {
        if (root == null)
            return 0;

        return 1
            + Math.Max(depth(root.left), depth(root.right));
    }

    // Recursive function to check perfect tree
    static bool isPerfectRecur(Node root, int d)
    {
        // Empty tree is perfect
        if (root == null)
            return true;

        // Leaf node
        if (root.left == null && root.right == null)
            return d == 1;

        // If one child is missing
        if (root.left == null || root.right == null)
            return false;

        // Recur for left and right subtree
        return isPerfectRecur(root.left, d - 1)
            && isPerfectRecur(root.right, d - 1);
    }

    static bool isPerfect(Node root)
    {
        // Find depth
        int d = depth(root);

        return isPerfectRecur(root, d);
    }

    // Driver Code
    static void Main()
    {
        // Binary tree
        //           10
        //        /     \  
        //      20       30
        //     /  \     /  \
        //   40    50  60   70
        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);

        if (isPerfect(root)) {
            Console.WriteLine("True");
        }
        else {
            Console.WriteLine("False");
        }
    }
}
JavaScript
class Node {
  constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
  }
}

// Function to find depth of tree
function depth(root) {
  if (root === null)
    return 0;

  return 1 + Math.max(depth(root.left), depth(root.right));
}

// Recursive function to check perfect tree
function isPerfectRecur(root, d) {
  // Empty tree is perfect
  if (root === null)
    return true;

  // Leaf node
  if (root.left === null && root.right === null)
    return d === 1;

  // If one child is missing
  if (root.left === null || root.right === null)
    return false;

  // Recur for left and right subtree
  return isPerfectRecur(root.left, d - 1) && isPerfectRecur(root.right, d - 1);
}

function isPerfect(root) {
  // Find depth
  const d = depth(root);

  return isPerfectRecur(root, d);
}

// Driver Code
// Binary tree
//           10
//        /     \
//      20       30
//     /  \     /  \
//   40    50  60   70
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);

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>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;

    Node(int x)
    {
        data = x;
        left = right = nullptr;
    }
};

// Recursive function to check perfect binary tree
bool solve(Node *root, int level, int &leafLevel)
{
    // Empty tree is perfect
    if (root == nullptr)
        return true;

    // If leaf node
    if (root->left == nullptr && root->right == nullptr)
    {
        // Store level of first leaf node
        if (leafLevel == -1)
            leafLevel = level;

        // All leaf nodes must be at same level
        return level == leafLevel;
    }

    // If one child is missing
    if (root->left == nullptr || root->right == nullptr)
    {
        return false;
    }

    // Recur for left and right subtree
    return solve(root->left, level + 1, leafLevel) && solve(root->right, level + 1, leafLevel);
}

// Function to check whether binary tree is perfect
bool isPerfect(Node *root)
{
    // Stores level of first leaf node
    int leafLevel = -1;

    return solve(root, 0, leafLevel);
}

// Driver Code
int main()
{
    // Binary tree
    //           10
    //        /     \
    //      20       30
    //     /  \     /  \
    //   40    50  60   70

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

    if (isPerfect(root))
    {
        cout << "True" << endl;
    }
    else
    {
        cout << "False" << endl;
    }

    return 0;
}
Java
/*
 * Recursive function to check perfect binary tree
 */
class Node {
    public int data;
    public Node left, right;

    public Node(int data) {
        this.data = data;
        this.left = this.right = null;
    }
}

public class GfG {
    private static int leafLevel = -1;

    private static boolean solve(Node root, int level) {
        
        // Empty tree is perfect
        if (root == null)
            return true;

        // If leaf node
        if (root.left == null && root.right == null) {
            
            // Store level of first leaf node
            if (leafLevel == -1)
                leafLevel = level;

            // All leaf nodes must be at same level
            return level == leafLevel;
        }

        // If one child is missing
        if (root.left == null || root.right == null)
            return false;

        // Recur for left and right subtree
        return solve(root.left, level + 1) && solve(root.right, level + 1);
    }

    public static boolean isPerfect(Node root) {
        
        // Stores level of first leaf node
        leafLevel = -1;

        return solve(root, 0);
    }

    public static void main(String[] args) {
        // Binary tree
        //           10
        //        /     \
        //      20       30
        //     /  \     /  \
        //   40    50  60   70

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

        if (isPerfect(root))
            System.out.println("True");
        else
            System.out.println("False");
    }
}
Python
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# Recursive function to check perfect binary tree
def solve(root, level, leafLevel):
    # Empty tree is perfect
    if root is None:
        return True

    # If leaf node
    if root.left is None and root.right is None:
        # Store level of first leaf node
        if leafLevel[0] == -1:
            leafLevel[0] = level

        # All leaf nodes must be at same level
        return level == leafLevel[0]

    # If one child is missing
    if root.left is None or root.right is None:
        return False

    # Recur for left and right subtree
    return solve(root.left, level + 1, leafLevel) and solve(root.right, level + 1, leafLevel)

# Function to check whether binary tree is perfect
def isPerfect(root):
    # Stores level of first leaf node
    leafLevel = [-1]

    return solve(root, 0, leafLevel)

# Driver Code
if __name__ == '__main__':
    # Binary tree
    #           10
    #        /     \
    #      20       30
    #     /  \     /  \
    #   40    50  60   70

    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)

    if isPerfect(root):
        print('True')
    else:
        print('False')
C#
using System;

public class Node
{
    public int data;
    public Node left, right;

    public Node(int data)
    {
        this.data = data;
        this.left = this.right = null;
    }
}

public class GfG
{
    private static int leafLevel = -1;

    private static bool Solve(Node root, int level)
    {
        // Empty tree is perfect
        if (root == null)
            return true;

        // If leaf node
        if (root.left == null && root.right == null)
        {
            // Store level of first leaf node
            if (leafLevel == -1)
                leafLevel = level;

            // All leaf nodes must be at same level
            return level == leafLevel;
        }

        // If one child is missing
        if (root.left == null || root.right == null)
            return false;

        // Recur for left and right subtree
        return Solve(root.left, level + 1) && Solve(root.right, level + 1);
    }

    public static bool IsPerfect(Node root)
    {
        // Stores level of first leaf node
        leafLevel = -1;

        return Solve(root, 0);
    }

    public static void Main(string[] args)
    {
        // Binary tree
        //           10
        //        /     \
        //      20       30
        //     /  \     /  \
        //   40    50  60   70

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

        if (IsPerfect(root))
            Console.WriteLine("True");
        else
            Console.WriteLine("False");
    }
}
JavaScript
class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

// Recursive function to check perfect binary tree
function solve(root, level, leafLevel) {
    // Empty tree is perfect
    if (root === null)
        return true;

    // If leaf node
    if (root.left === null && root.right === null) {
        // Store level of first leaf node
        if (leafLevel[0] === -1)
            leafLevel[0] = level;

        // All leaf nodes must be at same level
        return level === leafLevel[0];
    }

    // If one child is missing
    if (root.left === null || root.right === null)
        return false;

    // Recur for left and right subtree
    return solve(root.left, level + 1, leafLevel) && solve(root.right, level + 1, leafLevel);
}

// Function to check whether binary tree is perfect
function isPerfect(root) {
    // Stores level of first leaf node
    let leafLevel = [-1];

    return solve(root, 0, leafLevel);
}

// Driver Code
// Binary tree
//           10
//        /     \
//      20       30
//     /  \     /  \
//   40    50  60   70

let 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);

if (isPerfect(root))
    console.log('True');
else
    console.log('False');

Output
True
Comment