Perfect Binary Tree (original) (raw)
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]
**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]
**Output: false
Table of Content
- [Naive Method] Two Traversals - O(n) Time and O(h) Space
- [Expected Approach] Single DFS Traversal - O(n) Time and O(h) Space
[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'); }
`
[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');
`

