A complete binary tree is defined as a binary tree in which every level, except possibly the deepest, is completely filled. At deepest level, all nodes must be as far left a
//Helper function
int depth (struct tree * n)
{
int ld,rd;
if (n == NULL) return 0;
ld=depth(n->left);
ld=depth(n->right);
if (ld>rd)
return (1+ld);
else
return (1+rd);
}
//Core function
int isComplete (struct tree * n)
{
int ld,rd;
if (n == NULL) return TRUE;
ld=depth(n->left);
rd=depth(n->right);
return(ld==rd && isComplete(n->left) && isComplete(n->right));
}
First, count the number of nodes in the binary tree. Write a recursive function. If the received node is null, it returns true. If the index of the node is greater than or equal number of nodes, the tree is not binary. If none of these two happened, check the left and right sub-trees. import java.util.LinkedList; import java.util.Queue;
public class FBCompleteTree {
/*
public class TreeNode {
Integer val;
TreeNode left;
TreeNode right;
TreeNode(Integer x) {
val = x;
}
}
*/
public static void main(String[] args) {
TreeNode node1 = new TreeNode(1);
TreeNode node2 = new TreeNode(2);
TreeNode node3 = new TreeNode(3);
TreeNode node4 = new TreeNode(4);
TreeNode node5 = new TreeNode(5);
TreeNode node6 = new TreeNode(6);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
FBCompleteTree completeTree = new FBCompleteTree();
System.out.println(completeTree.isCompleteTree(node1));
}
public boolean isCompleteTree(TreeNode root) {
int nodeCount = countNodes(root);
// The index of the root is always zero.
return isComplete(root, nodeCount, 0);
}
/**
* Tells us if a binary tree is complete or not.
*
* @param node The current node
* @param nodeCount The node counts of the tree
* @param index The index of the node
* @return If a binary tree is complete or not
*/
private boolean isComplete(TreeNode node, int nodeCount, int index) {
// Null is a complete binary tree
if (node == null)
return true;
// In a complete binary tree, index of all the nodes should be less than nodes count.
if (index >= nodeCount)
return false;
/*
The index of the left child is 2*i+1 and the right child is 2*i+2 in a binary tree.
*/
return isComplete(node.left, nodeCount, 2 * index + 1)
&&
isComplete(node.right, nodeCount, 2 * index + 2);
}
/**
* Counts the number of nodes.
*
* @param root The root of the tree
* @return The number of nodes in the tree
*/
private int countNodes(TreeNode root) {
if (root == null)
return 0;
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
int counter = 0;
while (!q.isEmpty()) {
TreeNode currentNode = q.poll();
counter++;
TreeNode l = currentNode.left;
if (l != null) {
q.add(l);
}
TreeNode r = currentNode.right;
if (r != null) {
q.add(r);
}
}
return counter;
}
}
I hope it helps.
You can do it recursively by comparing the heights of each node's children. There may be at most one node where the left child has a height exactly one greater than the right child; all other nodes must be perfectly balanced.
You can also solve this problem by using level order traversal. The procedure is as follows:
Here is a c++ code:
My tree node is:
struct node{
int data;
node *left, *right;
};
void checkcomplete(){//checks whether a tree is complete or not by performing level order traversal
node *curr = root;
queue<node *> Q;
vector<int> arr;
int lastentry = 0;
Q.push(curr);
int currlevel = 1, nextlevel = 0;
while( currlevel){
node *temp = Q.front();
Q.pop();
currlevel--;
if(temp){
arr.push_back(temp->data);
lastentry = arr.size();
Q.push(temp->left);
Q.push(temp->right);
nextlevel += 2;
}else
arr.push_back(INT_MIN);
if(!currlevel){
currlevel = nextlevel;
nextlevel = 0;
}
}
int flag = 0;
for( int i = 0; i<lastentry && !flag; i++){
if( arr[i] == INT_MIN){
cout<<"Not a complete binary tree"<<endl;
flag = 1;
}
}
if( !flag )
cout<<"Complete binary tree\n";
}
Here is a C code for checking if the binary tree is complete:
struct node
{
int data;
struct node * left;
struct node * right;
};
int flag;
int isComplete(struct node *root, int depth)
{
int ld, rd;
if (root==NULL) return depth;
else
{
ld = isComplete(root->left,depth+1);
rd = isComplete(root->right, depth+1);
if (ld==-1 || rd==-1) return -1;
else if (ld==rd) return ld;
else if (ld==rd-1 && flag==0)
{
flag=1;
return rd;
}
else return -1;
}
}
The way it works is:
If the depth of left subtree is same as depth of right subtree, it returns the depth up the hirearchy.
if the depth of left subtree is one more than the depth of right subtree, it returns depth of right subtree up the hirarchy and enables the flag.
If it finds that the depth of left subtree and right subtree and flag is already set, it returns -1 up the hierarchy.
In the end, if the function returns -1, it is not the complete subtree, else the value returned is the minimum depth of the tree.
You can tell if a given binary tree is a left-complete binary tree - better known as a binary heap by ensuring that every node with a right child also has a left child. See below
bool IsLeftComplete(tree)
{
if (!tree.Right.IsEmpty && tree.Left.IsEmpty)
//tree has a right child but no left child, therefore is not a heap
return false;
if (tree.Right.IsEmpty && tree.Left.IsEmpty)
//no sub-trees, thus is leaf node. All leaves are complete
return true;
//this level is left complete, check levels below
return IsLeftComplete(tree.Left) && IsLeftComplete(tree.Right);
}