Given the root of a binary tree, determine whether the tree satisfies the heap property.
Binary tree needs to fulfill the following two conditions for being a heap:
It should be a complete tree (i.e. Every level of the tree, except possibly the last, is completely filled, and all nodes are as far left as possible.).
Every node’s value should be greater than or equal to its child node (considering max-heap).
Examples:
Input:Â
Output: true Explanation : The binary tree is a complete binary tree, and every node’s value is greater than or equal to its children’s values. Therefore, all heap properties are satisfied, and the tree is a valid max-heap.
Input:Â
Output: false Explanation: Max heap property fails as child node with value 4 is greater than parent node with value 3.
Two Separate Recursive Checks - O(n) Time and O(h) Space
The idea is to recursively check the following.
To check if tree is complete, we assign an index to each node and check if left is at 2i + 1 and right at 2i + 2
To check greater, we recursively compare values of left and right children with the current
Detailed Steps
Count the total number of nodes in the binary tree.
Recursively check whether the tree is complete by assigning an index to each node.
For a node at index i, its left and right children are assigned indices 2i + 1 and 2i + 2.
If any node gets an index greater than or equal to the total number of nodes, the tree is not complete.
Recursively check the max-heap property: every parent must be greater than or equal to its children.
If both the completeness and max-heap conditions hold, return true; otherwise, return false.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Count total number of nodesintcountNodes(Node*root){if(root==nullptr)return0;return1+countNodes(root->left)+countNodes(root->right);}// Check if the tree is completeboolisComplete(Node*root,intindex,inttotalNodes){if(root==nullptr)returntrue;// If index is beyond total nodes, tree is not completeif(index>=totalNodes)returnfalse;returnisComplete(root->left,2*index+1,totalNodes)&&isComplete(root->right,2*index+2,totalNodes);}// Check max-heap propertyboolisMaxHeap(Node*root){if(root==nullptr)returntrue;if(root->left!=nullptr&&root->data<root->left->data)returnfalse;if(root->right!=nullptr&&root->data<root->right->data)returnfalse;returnisMaxHeap(root->left)&&isMaxHeap(root->right);}boolisHeap(Node*root){inttotalNodes=countNodes(root);returnisComplete(root,0,totalNodes)&&isMaxHeap(root);}intmain(){Node*root=newNode(97);root->left=newNode(46);root->right=newNode(37);root->left->left=newNode(12);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(31);cout<<(isHeap(root)?"true":"false");return0;}
C
#include<stdio.h>#include<stdbool.h>#include<stdlib.h>structNode{intdata;structNode*left;structNode*right;};structNode*newNode(intx){structNode*node=(structNode*)malloc(sizeof(structNode));node->data=x;node->left=NULL;node->right=NULL;returnnode;}// Count total number of nodesintcountNodes(structNode*root){if(root==NULL)return0;return1+countNodes(root->left)+countNodes(root->right);}// Check if the tree is completeboolisComplete(structNode*root,intindex,inttotalNodes){if(root==NULL)returntrue;// If index is beyond total nodes, tree is not completeif(index>=totalNodes)returnfalse;returnisComplete(root->left,2*index+1,totalNodes)&&isComplete(root->right,2*index+2,totalNodes);}// Check max-heap propertyboolisMaxHeap(structNode*root){if(root==NULL)returntrue;if(root->left!=NULL&&root->data<root->left->data)returnfalse;if(root->right!=NULL&&root->data<root->right->data)returnfalse;returnisMaxHeap(root->left)&&isMaxHeap(root->right);}boolisHeap(structNode*root){inttotalNodes=countNodes(root);returnisComplete(root,0,totalNodes)&&isMaxHeap(root);}intmain(){structNode*root=newNode(97);root->left=newNode(46);root->right=newNode(37);root->left->left=newNode(12);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(31);printf("%s",isHeap(root)?"true":"false");return0;}
Java
classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=null;right=null;}}classGfG{// Count total number of nodesstaticintcountNodes(Noderoot){if(root==null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check if the tree is completestaticbooleanisComplete(Noderoot,intindex,inttotalNodes){if(root==null)returntrue;// If index is beyond total nodes, tree is not completeif(index>=totalNodes)returnfalse;returnisComplete(root.left,2*index+1,totalNodes)&&isComplete(root.right,2*index+2,totalNodes);}// Check max-heap propertystaticbooleanisMaxHeap(Noderoot){if(root==null)returntrue;if(root.left!=null&&root.data<root.left.data)returnfalse;if(root.right!=null&&root.data<root.right.data)returnfalse;returnisMaxHeap(root.left)&&isMaxHeap(root.right);}staticbooleanisHeap(Noderoot){inttotalNodes=countNodes(root);returnisComplete(root,0,totalNodes)&&isMaxHeap(root);}publicstaticvoidmain(String[]args){Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);System.out.println(isHeap(root)?"true":"false");}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Count total number of nodesdefcountNodes(root):ifrootisNone:return0return1+countNodes(root.left)+countNodes(root.right)# Check if the tree is completedefisComplete(root,index,totalNodes):ifrootisNone:returnTrue# If index is beyond total nodes, tree is not completeifindex>=totalNodes:returnFalsereturn(isComplete(root.left,2*index+1,totalNodes)andisComplete(root.right,2*index+2,totalNodes))# Check max-heap propertydefisMaxHeap(root):ifrootisNone:returnTrueifroot.leftisnotNoneandroot.data<root.left.data:returnFalseifroot.rightisnotNoneandroot.data<root.right.data:returnFalsereturnisMaxHeap(root.left)andisMaxHeap(root.right)defisHeap(root):totalNodes=countNodes(root)returnisComplete(root,0,totalNodes)andisMaxHeap(root)if__name__=="__main__":root=Node(97)root.left=Node(46)root.right=Node(37)root.left.left=Node(12)root.left.right=Node(3)root.right.left=Node(7)root.right.right=Node(31)print("true"ifisHeap(root)else"false")
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Count total number of nodesstaticintcountNodes(Noderoot){if(root==null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check if the tree is completestaticboolisComplete(Noderoot,intindex,inttotalNodes){if(root==null)returntrue;// If index is beyond total nodes, tree is not completeif(index>=totalNodes)returnfalse;returnisComplete(root.left,2*index+1,totalNodes)&&isComplete(root.right,2*index+2,totalNodes);}// Check max-heap propertystaticboolisMaxHeap(Noderoot){if(root==null)returntrue;if(root.left!=null&&root.data<root.left.data)returnfalse;if(root.right!=null&&root.data<root.right.data)returnfalse;returnisMaxHeap(root.left)&&isMaxHeap(root.right);}staticboolisHeap(Noderoot){inttotalNodes=countNodes(root);returnisComplete(root,0,totalNodes)&&isMaxHeap(root);}staticvoidMain(){Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);Console.WriteLine(isHeap(root)?"true":"false");}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Count total number of nodesfunctioncountNodes(root){if(root===null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check if the tree is completefunctionisComplete(root,index,totalNodes){if(root===null)returntrue;// If index is beyond total nodes, tree is not completeif(index>=totalNodes)returnfalse;returnisComplete(root.left,2*index+1,totalNodes)&&isComplete(root.right,2*index+2,totalNodes);}// Check max-heap propertyfunctionisMaxHeap(root){if(root===null)returntrue;if(root.left!==null&&root.data<root.left.data)returnfalse;if(root.right!==null&&root.data<root.right.data)returnfalse;returnisMaxHeap(root.left)&&isMaxHeap(root.right);}functionisHeap(root){consttotalNodes=countNodes(root);returnisComplete(root,0,totalNodes)&&isMaxHeap(root);}// Driver codeconstroot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);console.log(isHeap(root)?"true":"false");
Output
true
Single Recursion - O(n) Time and O(h) Space
We check the max-heap property and completeness together during a single recursive traversal. For each node, verify its position and compare its value with its children.
Step by Step Approach:
Start from the root with an index representing its position in the complete binary tree.
For each node, check whether its index is within the total number of nodes. If not, the tree is not complete.
Check that the node is greater than or equal to its left and right children.
Recursively apply the same checks to the left and right subtrees.
Leaf nodes automatically satisfy the heap property because they have no children.
If every node passes both checks, the tree is a valid max-heap.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Count total number of nodesintcountNodes(Node*root){if(root==nullptr)return0;return1+countNodes(root->left)+countNodes(root->right);}// Check completeness and max-heap propertyboolcheckHeap(Node*root,intindex,inttotalNodes){if(root==nullptr)returntrue;// Check if the tree is completeif(index>=totalNodes)returnfalse;// Check max-heap propertyif(root->left!=nullptr&&root->data<root->left->data)returnfalse;if(root->right!=nullptr&&root->data<root->right->data)returnfalse;returncheckHeap(root->left,2*index+1,totalNodes)&&checkHeap(root->right,2*index+2,totalNodes);}boolisHeap(Node*root){inttotalNodes=countNodes(root);returncheckHeap(root,0,totalNodes);}intmain(){Node*root=newNode(97);root->left=newNode(46);root->right=newNode(37);root->left->left=newNode(12);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(31);cout<<(isHeap(root)?"true":"false");return0;}
C
#include<stdio.h>#include<stdlib.h>#include<stdbool.h>structNode{intdata;structNode*left;structNode*right;};structNode*newNode(intx){structNode*node=malloc(sizeof(structNode));node->data=x;node->left=NULL;node->right=NULL;returnnode;}// Count total number of nodesintcountNodes(structNode*root){if(root==NULL)return0;return1+countNodes(root->left)+countNodes(root->right);}// Check completeness and max-heap propertyboolcheckHeap(structNode*root,intindex,inttotalNodes){if(root==NULL)returntrue;// Check if the tree is completeif(index>=totalNodes)returnfalse;// Check max-heap propertyif(root->left!=NULL&&root->data<root->left->data)returnfalse;if(root->right!=NULL&&root->data<root->right->data)returnfalse;returncheckHeap(root->left,2*index+1,totalNodes)&&checkHeap(root->right,2*index+2,totalNodes);}boolisHeap(structNode*root){inttotalNodes=countNodes(root);returncheckHeap(root,0,totalNodes);}intmain(){structNode*root=newNode(97);root->left=newNode(46);root->right=newNode(37);root->left->left=newNode(12);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(31);printf("%s",isHeap(root)?"true":"false");return0;}
Java
classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=null;right=null;}}classGfG{// Count total number of nodesstaticintcountNodes(Noderoot){if(root==null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check completeness and max-heap propertystaticbooleancheckHeap(Noderoot,intindex,inttotalNodes){if(root==null)returntrue;// Check if the tree is completeif(index>=totalNodes)returnfalse;// Check max-heap propertyif(root.left!=null&&root.data<root.left.data)returnfalse;if(root.right!=null&&root.data<root.right.data)returnfalse;returncheckHeap(root.left,2*index+1,totalNodes)&&checkHeap(root.right,2*index+2,totalNodes);}staticbooleanisHeap(Noderoot){inttotalNodes=countNodes(root);returncheckHeap(root,0,totalNodes);}publicstaticvoidmain(String[]args){Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);System.out.println(isHeap(root));}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Count total number of nodesdefcountNodes(root):ifrootisNone:return0return1+countNodes(root.left)+countNodes(root.right)# Check completeness and max-heap propertydefcheckHeap(root,index,totalNodes):ifrootisNone:returnTrue# Check if the tree is completeifindex>=totalNodes:returnFalse# Check max-heap propertyifroot.leftisnotNoneandroot.data<root.left.data:returnFalseifroot.rightisnotNoneandroot.data<root.right.data:returnFalsereturn(checkHeap(root.left,2*index+1,totalNodes)andcheckHeap(root.right,2*index+2,totalNodes))defisHeap(root):totalNodes=countNodes(root)returncheckHeap(root,0,totalNodes)# Driver coderoot=Node(97)root.left=Node(46)root.right=Node(37)root.left.left=Node(12)root.left.right=Node(3)root.right.left=Node(7)root.right.right=Node(31)print("true"ifisHeap(root)else"false")
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Count total number of nodesstaticintcountNodes(Noderoot){if(root==null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check completeness and max-heap propertystaticboolcheckHeap(Noderoot,intindex,inttotalNodes){if(root==null)returntrue;// Check if the tree is completeif(index>=totalNodes)returnfalse;// Check max-heap propertyif(root.left!=null&&root.data<root.left.data)returnfalse;if(root.right!=null&&root.data<root.right.data)returnfalse;returncheckHeap(root.left,2*index+1,totalNodes)&&checkHeap(root.right,2*index+2,totalNodes);}staticboolisHeap(Noderoot){inttotalNodes=countNodes(root);returncheckHeap(root,0,totalNodes);}staticvoidMain(){Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);Console.WriteLine(isHeap(root)?"true":"false");}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Count total number of nodesfunctioncountNodes(root){if(root===null)return0;return1+countNodes(root.left)+countNodes(root.right);}// Check completeness and max-heap propertyfunctioncheckHeap(root,index,totalNodes){if(root===null)returntrue;// Check if the tree is completeif(index>=totalNodes)returnfalse;// Check max-heap propertyif(root.left!==null&&root.data<root.left.data)returnfalse;if(root.right!==null&&root.data<root.right.data)returnfalse;returncheckHeap(root.left,2*index+1,totalNodes)&&checkHeap(root.right,2*index+2,totalNodes);}functionisHeap(root){consttotalNodes=countNodes(root);returncheckHeap(root,0,totalNodes);}// Driver codeconstroot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);console.log(isHeap(root)?"true":"false");
Output
true
Level Order Traversal - O(n) Time and O(n) Space
Use level order traversal (BFS) to check both conditions of a max-heap. While traversing level by level, verify the heap property and use a flag to ensure the tree remains complete.
Step by Step approach :
Start a level order traversal using a queue.
For each node, check that its value is greater than or equal to its children.
If a node is missing a left or right child, set a flag indicating that all following nodes must be leaf nodes.
If any later node has a child after the flag is set, the tree is not complete.
If any node violates the max-heap property, return false.
If the entire traversal completes without violations, return true.
C++
#include<iostream>#include<vector>#include<queue>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intk){data=k;left=nullptr;right=nullptr;}};boolisHeap(Node*root){queue<Node*>q;q.push(root);// Flag indicates if a node// with missing children has been seenboolflag=false;while(!q.empty()){Node*temp=q.front();q.pop();// Check left childif(temp->left){// If a node with missing child was seen before // or if left child is bigger than parent, the heap rules are brokenif(flag||temp->left->data>temp->data){returnfalse;}q.push(temp->left);}else{// Left child is missing; set//flag indicating last node encounteredflag=true;}// Check right childif(temp->right){// Same checks as left childif(flag||temp->right->data>temp->data){returnfalse;}q.push(temp->right);}else{// Right child is missing; set flagflag=true;}}returntrue;}intmain(){// Construct the Binary Tree// 97// / \ // 46 37// / \ / \ // 12 3 7 31// / \ // 6 9Node*root=newNode(97);root->left=newNode(46);root->right=newNode(37);root->left->left=newNode(12);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(31);root->left->left->left=newNode(6);root->left->left->right=newNode(9);if(isHeap(root)){cout<<"true"<<endl;}else{cout<<"false"<<endl;}return0;}
Java
importjava.util.Queue;importjava.util.LinkedList;// Node StructureclassNode{intdata;Nodeleft;Noderight;Node(intk){data=k;left=null;right=null;}}publicclassGFG{publicstaticbooleanisHeap(Noderoot){Queue<Node>q=newLinkedList<>();q.add(root);// Flag indicates if a node//with missing children has been seenbooleanflag=false;while(!q.isEmpty()){Nodetemp=q.poll();// Check left childif(temp.left!=null){// If a node with missing child was seen before // or if left child is bigger than parent, the heap rules are brokenif(flag||temp.left.data>temp.data){returnfalse;}q.add(temp.left);}else{// Left child is missing; set//flag indicating last node encounteredflag=true;}// Check right childif(temp.right!=null){// Same checks as left childif(flag||temp.right.data>temp.data){returnfalse;}q.add(temp.right);}else{// Right child is missing; set flagflag=true;}}returntrue;}publicstaticvoidmain(String[]args){// Construct the Binary Tree// 97// / \// 46 37// / \ / \// 12 3 7 31// / \// 6 9Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);root.left.left.left=newNode(6);root.left.left.right=newNode(9);if(isHeap(root)){System.out.println("true");}else{System.out.println("false");}}}
Python
fromcollectionsimportdeque# Node StructureclassNode:def__init__(self,k):self.data=kself.left=Noneself.right=NonedefisHeap(root):q=deque()q.append(root)# Flag indicates if a node#with missing children has been seenflag=Falsewhileq:temp=q.popleft()# Check left childiftemp.left:# If a node with missing child was seen before # or if left child is bigger than parent, the heap rules are brokenifflagortemp.left.data>temp.data:returnFalseq.append(temp.left)else:# Left child is missing; set#flag indicating last node encounteredflag=True# Check right childiftemp.right:# Same checks as left childifflagortemp.right.data>temp.data:returnFalseq.append(temp.right)else:# Right child is missing; set flagflag=TruereturnTrueif__name__=="__main__":# Construct the Binary Tree# 97# / \# 46 37# / \ / \# 12 3 7 31# / \# 6 9root=Node(97)root.left=Node(46)root.right=Node(37)root.left.left=Node(12)root.left.right=Node(3)root.right.left=Node(7)root.right.right=Node(31)root.left.left.left=Node(6)root.left.left.right=Node(9)ifisHeap(root):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intk){data=k;left=null;right=null;}}classGFG{staticboolisHeap(Noderoot){Queue<Node>q=newQueue<Node>();q.Enqueue(root);// Flag indicates if a node//with missing children has been seenboolflag=false;while(q.Count>0){Nodetemp=q.Dequeue();// Check left childif(temp.left!=null){// If a node with missing child was seen before // or if left child is bigger than parent, the heap rules are brokenif(flag||temp.left.data>temp.data){returnfalse;}q.Enqueue(temp.left);}else{// Left child is missing; set//flag indicating last node encounteredflag=true;}// Check right childif(temp.right!=null){// Same checks as left childif(flag||temp.right.data>temp.data){returnfalse;}q.Enqueue(temp.right);}else{// Right child is missing; set flagflag=true;}}returntrue;}staticvoidMain(string[]args){// Construct the Binary Tree// 97// / \// 46 37// / \ / \// 12 3 7 31// / \// 6 9Noderoot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);root.left.left.left=newNode(6);root.left.left.right=newNode(9);if(isHeap(root)){Console.WriteLine("true");}else{Console.WriteLine("false");}}}
JavaScript
// Node StructureclassNode{constructor(k){this.data=k;this.left=null;this.right=null;}}// Custom Queue ImplementationclassQueue{constructor(){this.items=[];this.frontIndex=0;}enqueue(element){this.items.push(element);}dequeue(){if(this.isEmpty())returnnull;returnthis.items[this.frontIndex++];}isEmpty(){returnthis.frontIndex>=this.items.length;}}functionisHeap(root){letq=newQueue();q.enqueue(root);// Flag indicates if a node// with missing children has been seenletflag=false;while(!q.isEmpty()){lettemp=q.dequeue();// Check left childif(temp.left){// If a node with missing child was seen before // or if left child is bigger than parent, the heap rules are brokenif(flag||temp.left.data>temp.data){returnfalse;}q.enqueue(temp.left);}else{// Left child is missing; set// flag indicating last node encounteredflag=true;}// Check right childif(temp.right){// Same checks as left childif(flag||temp.right.data>temp.data){returnfalse;}q.enqueue(temp.right);}else{// Right child is missing; set flagflag=true;}}returntrue;}// Driver Code// Construct the Binary Tree// 97// / \// 46 37// / \ / \// 12 3 7 31// / \// 6 9letroot=newNode(97);root.left=newNode(46);root.right=newNode(37);root.left.left=newNode(12);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(31);root.left.left.left=newNode(6);root.left.left.right=newNode(9);if(isHeap(root)){console.log("true");}else{console.log("false");}