Given the root of a Binary Tree, check whether the given Binary Tree is a Complete Binary Tree or not. A complete binary tree is a binary tree where every level is fully filled except possibly the last, and all nodes in the last level occupy the leftmost positions.
Examples:
Input: root = [4, 2, 9] Output: false Explanation: The given tree is a complete binary tree.
Input: root = [1, 2, 3, 4, 5] Output: true Explanation: The tree is complete since the nodes 4 and 5 are filled from left to right without gaps.
Input: root = [10, 2, 11, 1, 5, N, N, N, N, 3, 6, 4] Output: false Explanation: The given tree is not a complete binary tree as the 4th level break the rules.
Using Node Indexing(recursive) - O(n) Time and O(h) Space
The idea is to assign indices to nodes as they would appear in the array representation of a complete binary tree. Starting with index 0 for the root, the left and right children of a node at index i are assigned indices 2 * i + 1 and 2 * i + 2 respectively. First count the total number of nodes n, then recursively traverse the tree and check these indices. If any node receives an index greater than or equal to n, it indicates a gap in the tree structure, so the tree is not complete.
C++
#include<iostream>usingnamespacestd;// Binary tree nodeclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};// Counts the total number of nodes in the treeintcountNodes(Node*root){if(!root){return0;}return1+countNodes(root->left)+countNodes(root->right);}// Recursively checks whether the tree is completeboolcheckComplete(Node*root,intidx,inttotal){if(!root){returntrue;}// If a node gets an index outside the valid range,// then there is a gap in the treeif(idx>=total){returnfalse;}// Check left and right subtrees using array-style indicesreturncheckComplete(root->left,2*idx+1,total)&&checkComplete(root->right,2*idx+2,total);}// Returns true if the binary tree is completeboolisCompleteBT(Node*root){inttotal=countNodes(root);// Start indexing from 0 for the rootreturncheckComplete(root,0,total);}intmain(){Node*root=newNode(4);root->left=newNode(2);root->right=newNode(9);if(isCompleteBT(root)){cout<<"true\n";}else{cout<<"false\n";}return0;}
Java
// Binary tree nodeclassNode{publicintdata;publicNodeleft;publicNoderight;Node(intval){data=val;left=right=null;}}publicclassGFG{// Counts the total number of nodes in the treepublicstaticintcountNodes(Noderoot){if(root==null){return0;}return1+countNodes(root.left)+countNodes(root.right);}// Recursively checks whether the tree is completepublicstaticbooleancheckComplete(Noderoot,intidx,inttotal){if(root==null){returntrue;}// If a node gets an index outside the valid range,// then there is a gap in the treeif(idx>=total){returnfalse;}// Check left and right subtrees using array-style indicesreturncheckComplete(root.left,2*idx+1,total)&&checkComplete(root.right,2*idx+2,total);}// Returns true if the binary tree is completepublicstaticbooleanisCompleteBT(Noderoot){inttotal=countNodes(root);// Start indexing from 0 for the rootreturncheckComplete(root,0,total);}publicstaticvoidmain(String[]args){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root)){System.out.println("true");}else{System.out.println("false");}}}
Python
# Binary tree nodeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Counts the total number of nodes in the treedefcountNodes(root):ifnotroot:return0return1+countNodes(root.left)+countNodes(root.right)# Recursively checks whether the tree is completedefcheckComplete(root,idx,total):ifnotroot:returnTrue# If a node gets an index outside the valid range,# then there is a gap in the treeifidx>=total:returnFalse# Check left and right subtrees using array-style indicesreturncheckComplete(root.left,2*idx+1,total)and \
checkComplete(root.right,2*idx+2,total)# Returns true if the binary tree is completedefisCompleteBT(root):total=countNodes(root)# Start indexing from 0 for the rootreturncheckComplete(root,0,total)if__name__=='__main__':root=Node(4)root.left=Node(2)root.right=Node(9)ifisCompleteBT(root):print('true')else:print('false')
C#
// Binary tree nodepublicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassGFG{// Counts the total number of nodes in the treepublicstaticintCountNodes(Noderoot){if(root==null){return0;}return1+CountNodes(root.left)+CountNodes(root.right);}// Recursively checks whether the tree is completepublicstaticboolCheckComplete(Noderoot,intidx,inttotal){if(root==null){returntrue;}// If a node gets an index outside the valid range,// then there is a gap in the treeif(idx>=total){returnfalse;}// Check left and right subtrees using array-style indicesreturnCheckComplete(root.left,2*idx+1,total)&&CheckComplete(root.right,2*idx+2,total);}// Returns true if the binary tree is completepublicstaticboolisCompleteBT(Noderoot){inttotal=CountNodes(root);// Start indexing from 0 for the rootreturnCheckComplete(root,0,total);}publicstaticvoidMain(){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root)){System.Console.WriteLine("true");}else{System.Console.WriteLine("false");}}}
JavaScript
// Binary tree nodeclassNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Counts the total number of nodes in the treefunctioncountNodes(root){if(root===null){return0;}return1+countNodes(root.left)+countNodes(root.right);}// Recursively checks whether the tree is completefunctioncheckComplete(root,idx,total){if(root===null){returntrue;}// If a node gets an index outside the valid range,// then there is a gap in the treeif(idx>=total){returnfalse;}// Check left and right subtrees using array-style indicesreturncheckComplete(root.left,2*idx+1,total)&&checkComplete(root.right,2*idx+2,total);}// Returns true if the binary tree is completefunctionisCompleteBT(root){lettotal=countNodes(root);// Start indexing from 0 for the rootreturncheckComplete(root,0,total);}// Driver codeletroot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root)){console.log('true');}else{console.log('false');}
Output
true
Using Level-Order Traversal - O(n) Time and O(n) Space
The idea is to do a level order traversal starting from the root. In the traversal, once a node is found which is Not a Full Node, all the following nodes must be leaf nodes. A node is ‘Full Node’ if both left and right children are not empty (or not NULL).Â
Also, one more thing needs to be checked to handle the below case: If a node has an empty left child, then the right child must be empty. Â
C++
#include<iostream>#include<queue>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};boolisCompleteBT(Node*root){if(root==nullptr)returntrue;queue<Node*>q;q.push(root);boolend=false;while(!q.empty()){Node*current=q.front();q.pop();// Check left childif(current->left){if(end)returnfalse;q.push(current->left);}else{// If left child is missing,// mark the endend=true;}// Check right childif(current->right){if(end)returnfalse;q.push(current->right);}else{// If right child is missing,// mark the endend=true;}}returntrue;}intmain(){Node*root=newNode(4);root->left=newNode(2);root->right=newNode(9);if(isCompleteBT(root))cout<<"true"<<endl;elsecout<<"false"<<endl;return0;}
Java
importjava.util.LinkedList;importjava.util.Queue;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassGFG{publicstaticbooleanisCompleteBT(Noderoot){if(root==null)returntrue;Queue<Node>q=newLinkedList<>();q.add(root);booleanend=false;while(!q.isEmpty()){Nodecurrent=q.poll();// Check left childif(current.left!=null){if(end)returnfalse;q.add(current.left);}else{// If left child is missing,// mark the endend=true;}// Check right childif(current.right!=null){if(end)returnfalse;q.add(current.right);}else{// If right child is missing,// mark the endend=true;}}returntrue;}publicstaticvoidmain(String[]args){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root))System.out.println("true");elseSystem.out.println("false");}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=NonedefisCompleteBT(root):ifrootisNone:returnTrueq=deque([root])end=Falsewhileq:current=q.popleft()# Check left childifcurrent.leftisnotNone:ifend:returnFalseq.append(current.left)else:# If left child is missing,# mark the endend=True# Check right childifcurrent.rightisnotNone:ifend:returnFalseq.append(current.right)else:# If right child is missing,# mark the endend=TruereturnTrueif__name__=='__main__':root=Node(4)root.left=Node(2)root.right=Node(9)ifisCompleteBT(root):print('true')else:print('false')
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassGFG{publicstaticboolisCompleteBT(Noderoot){if(root==null)returntrue;Queue<Node>q=newQueue<Node>();q.Enqueue(root);boolend=false;while(q.Count>0){Nodecurrent=q.Dequeue();// Check left childif(current.left!=null){if(end)returnfalse;q.Enqueue(current.left);}else{// If left child is missing,// mark the endend=true;}// Check right childif(current.right!=null){if(end)returnfalse;q.Enqueue(current.right);}else{// If right child is missing,// mark the endend=true;}}returntrue;}publicstaticvoidMain(){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functionisCompleteBT(root){if(root===null)returntrue;letq=[root];letend=false;while(q.length>0){letcurrent=q.shift();// Check left childif(current.left!==null){if(end)returnfalse;q.push(current.left);}else{// If left child is missing,// mark the endend=true;}// Check right childif(current.right!==null){if(end)returnfalse;q.push(current.right);}else{// If right child is missing,// mark the endend=true;}}returntrue;}// Driver codeletroot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root))console.log('true');elseconsole.log('false');
Output
true
Checking Position of null -Â O(n) Time and O(n) Space
A simple idea would be to check whether the null Node encountered is the last node of the Binary Tree. If the null node encountered in the binary tree is the last node then it is a complete binary tree and if there exists a valid node even after encountering a null node then the tree is not a complete binary tree.
C++
#include<iostream>#include<queue>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};boolisCompleteBT(Node*root){if(root==nullptr){returntrue;}queue<Node*>q;q.push(root);boolnullEncountered=false;while(!q.empty()){Node*curr=q.front();q.pop();if(curr==NULL){// If we have seen a NULL node, we // set the flag to truenullEncountered=true;}else{// If that NULL node is not the last node then// return falseif(nullEncountered==true){returnfalse;}// Push both nodes even if // there are nullq.push(curr->left);q.push(curr->right);}}returntrue;}intmain(){Node*root=newNode(4);root->left=newNode(2);root->right=newNode(9);if(isCompleteBT(root)){cout<<"true"<<endl;}else{cout<<"false"<<endl;}return0;}
Java
importjava.util.Queue;importjava.util.LinkedList;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassMain{publicstaticbooleanisCompleteBT(Noderoot){if(root==null){returntrue;}Queue<Node>q=newLinkedList<>();q.add(root);booleannullEncountered=false;while(!q.isEmpty()){Nodecurr=q.poll();if(curr==null){// If we have seen a NULL node, we // set the flag to truenullEncountered=true;}else{// If that NULL node is not the last node then// return falseif(nullEncountered==true){returnfalse;}// Push both nodes even if // there are nullq.add(curr.left);q.add(curr.right);}}returntrue;}publicstaticvoidmain(String[]args){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root)){System.out.println("true");}else{System.out.println("false");}}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=NoneclassSolution:defisCompleteBT(self,root):ifrootisNone:returnTrueq=deque([root])null_encountered=Falsewhileq:curr=q.popleft()ifcurrisNone:# A NULL position has been foundnull_encountered=Trueelse:# Non-NULL node after a NULL positionifnull_encountered:returnFalseq.append(curr.left)q.append(curr.right)returnTrueif__name__=="__main__":root=Node(4)root.left=Node(2)root.right=Node(9)ob=Solution()print(str(ob.isCompleteBT(root)).lower())
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassProgram{publicstaticboolisCompleteBT(Noderoot){if(root==null){returntrue;}Queue<Node>q=newQueue<Node>();q.Enqueue(root);boolnullEncountered=false;while(q.Count>0){Nodecurr=q.Dequeue();if(curr==null){// If we have seen a NULL node, we // set the flag to truenullEncountered=true;}else{// If that NULL node is not the last node then// return falseif(nullEncountered==true){returnfalse;}// Push both nodes even if // there are nullif(curr.left!=null){q.Enqueue(curr.left);}if(curr.right!=null){q.Enqueue(curr.right);}}}returntrue;}publicstaticvoidMain(){Noderoot=newNode(4);root.left=newNode(2);root.right=newNode(9);if(isCompleteBT(root)){Console.WriteLine("true");}else{Console.WriteLine("false");}}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}classSolution{isCompleteBT(root){if(root===null){returntrue;}letq=[root];letnullEncountered=false;while(q.length>0){letcurr=q.shift();if(curr===null){// A NULL position has been foundnullEncountered=true;}else{// Non-NULL node after a NULL positionif(nullEncountered){returnfalse;}q.push(curr.left);q.push(curr.right);}}returntrue;}}// Driver codeletroot=newNode(4);root.left=newNode(2);root.right=newNode(9);letob=newSolution();console.log(ob.isCompleteBT(root));