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
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++
// 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> |
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:
C++
#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; } |
Java
/*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 |
Python3
# 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." ) |
C#
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." ); } } } |
Javascript
//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++
// 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> |
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++
// 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 |
Java
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 |
Python3
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 |
C#
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 |
Javascript
// 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).
Contact Us