Check if a Binary Tree is Complete

Last Updated : 13 Jul, 2026

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.

Screenshot-from-2026-07-13-09-54-48

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.

2

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.

Screenshot-from-2026-07-13-09-57-17
Try It Yourself
redirect icon

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>
using namespace std;

// Binary tree node
class Node {
  public:
    int data;
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

// Counts the total number of nodes in the tree
int countNodes(Node* root) {
    if (!root) {
        return 0;
    }

    return 1 + countNodes(root->left) +
               countNodes(root->right);
}

// Recursively checks whether the tree is complete
bool checkComplete(Node* root, int idx, int total) {
    if (!root) {
        return true;
    }

    // If a node gets an index outside the valid range,
    // then there is a gap in the tree
    if (idx >= total) {
        return false;
    }

    // Check left and right subtrees using array-style indices
    return checkComplete(root->left, 2 * idx + 1, total) &&
           checkComplete(root->right, 2 * idx + 2, total);
}

// Returns true if the binary tree is complete
bool isCompleteBT(Node* root) {
    int total = countNodes(root);

    // Start indexing from 0 for the root
    return checkComplete(root, 0, total);
}

int main() {
    Node* root = new Node(4);
    root->left = new Node(2);
    root->right = new Node(9);

    if (isCompleteBT(root)) {
        cout << "true\n";
    } else {
        cout << "false\n";
    }

    return 0;
}
Java
// Binary tree node
class Node {
  public int data;
  public Node left;
  public Node right;

  Node(int val) {
      data = val;
      left = right = null;
  }
}

public class GFG {
  // Counts the total number of nodes in the tree
  public static int countNodes(Node root) {
      if (root == null) {
          return 0;
      }

      return 1 + countNodes(root.left) +
                 countNodes(root.right);
  }

  // Recursively checks whether the tree is complete
  public static boolean checkComplete(Node root, int idx, int total) {
      if (root == null) {
          return true;
      }

      // If a node gets an index outside the valid range,
      // then there is a gap in the tree
      if (idx >= total) {
          return false;
      }

      // Check left and right subtrees using array-style indices
      return checkComplete(root.left, 2 * idx + 1, total) &&
             checkComplete(root.right, 2 * idx + 2, total);
  }

  // Returns true if the binary tree is complete
  public static boolean isCompleteBT(Node root) {
      int total = countNodes(root);

      // Start indexing from 0 for the root
      return checkComplete(root, 0, total);
  }

  public static void main(String[] args) {
      Node root = new Node(4);
      root.left = new Node(2);
      root.right = new Node(9);

      if (isCompleteBT(root)) {
          System.out.println("true");
      } else {
          System.out.println("false");
      }
  }
}
Python
# Binary tree node
class Node:
  def __init__(self, val):
      self.data = val
      self.left = None
      self.right = None

# Counts the total number of nodes in the tree
def countNodes(root):
  if not root:
      return 0

  return 1 + countNodes(root.left) + countNodes(root.right)

# Recursively checks whether the tree is complete
def checkComplete(root, idx, total):
  if not root:
      return True

  # If a node gets an index outside the valid range,
  # then there is a gap in the tree
  if idx >= total:
      return False

  # Check left and right subtrees using array-style indices
  return checkComplete(root.left, 2 * idx + 1, total) and \
         checkComplete(root.right, 2 * idx + 2, total)

# Returns true if the binary tree is complete
def isCompleteBT(root):
  total = countNodes(root)

  # Start indexing from 0 for the root
  return checkComplete(root, 0, total)

if __name__ == '__main__':
  root = Node(4)
  root.left = Node(2)
  root.right = Node(9)

  if isCompleteBT(root):
      print('true')
  else:
      print('false')
C#
// Binary tree node
public class Node {
  public int data;
  public Node left;
  public Node right;

  public Node(int val) {
      data = val;
      left = right = null;
  }
}

public class GFG {
  // Counts the total number of nodes in the tree
  public static int CountNodes(Node root) {
      if (root == null) {
          return 0;
      }

      return 1 + CountNodes(root.left) +
              CountNodes(root.right);
  }

  // Recursively checks whether the tree is complete
  public static bool CheckComplete(Node root, int idx, int total) {
      if (root == null) {
          return true;
      }

      // If a node gets an index outside the valid range,
      // then there is a gap in the tree
      if (idx >= total) {
          return false;
      }

      // Check left and right subtrees using array-style indices
      return CheckComplete(root.left, 2 * idx + 1, total) &&
             CheckComplete(root.right, 2 * idx + 2, total);
  }

  // Returns true if the binary tree is complete
  public static bool isCompleteBT(Node root) {
      int total = CountNodes(root);

      // Start indexing from 0 for the root
      return CheckComplete(root, 0, total);
  }

  public static void Main() {
      Node root = new Node(4);
      root.left = new Node(2);
      root.right = new Node(9);

      if (isCompleteBT(root)) {
          System.Console.WriteLine("true");
      } else {
          System.Console.WriteLine("false");
      }
  }
}
JavaScript
// Binary tree node
class Node {
  constructor(val) {
      this.data = val;
      this.left = null;
      this.right = null;
  }
}

// Counts the total number of nodes in the tree
function countNodes(root) {
  if (root === null) {
      return 0;
  }

  return 1 + countNodes(root.left) +
           countNodes(root.right);
}

// Recursively checks whether the tree is complete
function checkComplete(root, idx, total) {
  if (root === null) {
      return true;
  }

  // If a node gets an index outside the valid range,
  // then there is a gap in the tree
  if (idx >= total) {
      return false;
  }

  // Check left and right subtrees using array-style indices
  return checkComplete(root.left, 2 * idx + 1, total) &&
         checkComplete(root.right, 2 * idx + 2, total);
}

// Returns true if the binary tree is complete
function isCompleteBT(root) {
  let total = countNodes(root);

  // Start indexing from 0 for the root
  return checkComplete(root, 0, total);
}

// Driver code
let root = new Node(4);
root.left = new Node(2);
root.right = new Node(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.  

Deletion-in-a--Binary-Tree-2
C++
#include <iostream>
#include <queue>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

bool isCompleteBT(Node* root) {
    if (root == nullptr)
        return true;

    queue<Node*> q;
    q.push(root);
    bool end = false; 

    while (!q.empty()) {
        Node* current = q.front();
        q.pop();

        // Check left child
        if (current->left) {
            if (end) 
                return false;
            q.push(current->left);
        } 
       else {
            
            // If left child is missing,
            // mark the end
            end = true;
        }

        // Check right child
        if (current->right) {
            if (end) 
                return false;
            q.push(current->right);
        } 
       else {
            
            // If right child is missing,
            // mark the end
            end = true;
        }
    }

    return true; 
}

int main() {
  
    Node* root = new Node(4);
    root->left = new Node(2);
    root->right = new Node(9);
    
    if (isCompleteBT(root))
        cout << "true" << endl;
    else
        cout << "false" << endl;

    return 0;
}
Java
import java.util.LinkedList;
import java.util.Queue;

class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static boolean isCompleteBT(Node root) {
        if (root == null)
            return true;

        Queue<Node> q = new LinkedList<>();
        q.add(root);
        boolean end = false;

        while (!q.isEmpty()) {
            Node current = q.poll();

            // Check left child
            if (current.left!= null) {
                if (end)
                    return false;
                q.add(current.left);
            } else {
                // If left child is missing,
                // mark the end
                end = true;
            }

            // Check right child
            if (current.right!= null) {
                if (end)
                    return false;
                q.add(current.right);
            } else {
                // If right child is missing,
                // mark the end
                end = true;
            }
        }

        return true;
    }

    public static void main(String[] args) {
        Node root = new Node(4);
        root.left = new Node(2);
        root.right = new Node(9);

        if (isCompleteBT(root))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
from collections import deque

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def isCompleteBT(root):
    if root is None:
        return True

    q = deque([root])
    end = False

    while q:
        current = q.popleft()

        # Check left child
        if current.left is not None:
            if end:
                return False
            q.append(current.left)
        else:
            # If left child is missing,
            # mark the end
            end = True

        # Check right child
        if current.right is not None:
            if end:
                return False
            q.append(current.right)
        else:
            # If right child is missing,
            # mark the end
            end = True

    return True

if __name__ == '__main__':
    root = Node(4)
    root.left = Node(2)
    root.right = Node(9)

    if isCompleteBT(root):
        print('true')
    else:
        print('false')
C#
using System;
using System.Collections.Generic;

public class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static bool isCompleteBT(Node root) {
        if (root == null)
            return true;

        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);
        bool end = false;

        while (q.Count > 0) {
            Node current = q.Dequeue();

            // Check left child
            if (current.left!= null) {
                if (end)
                    return false;
                q.Enqueue(current.left);
            } else {
                // If left child is missing,
                // mark the end
                end = true;
            }

            // Check right child
            if (current.right!= null) {
                if (end)
                    return false;
                q.Enqueue(current.right);
            } else {
                // If right child is missing,
                // mark the end
                end = true;
            }
        }

        return true;
    }

    public static void Main() {
        Node root = new Node(4);
        root.left = new Node(2);
        root.right = new Node(9);

        if (isCompleteBT(root))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function isCompleteBT(root) {
    if (root === null)
        return true;

    let q = [root];
    let end = false;

    while (q.length > 0) {
        let current = q.shift();

        // Check left child
        if (current.left!== null) {
            if (end)
                return false;
            q.push(current.left);
        } else {
            // If left child is missing,
            // mark the end
            end = true;
        }

        // Check right child
        if (current.right!== null) {
            if (end)
                return false;
            q.push(current.right);
        } else {
            // If right child is missing,
            // mark the end
            end = true;
        }
    }

    return true;
}

// Driver code
let root = new Node(4);
root.left = new Node(2);
root.right = new Node(9);

if (isCompleteBT(root))
    console.log('true');
else
    console.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>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};

bool isCompleteBT(Node* root) {
    if (root == nullptr) {
        return true;
    }

    queue<Node*> q;
    q.push(root);
    bool nullEncountered = 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 true
            nullEncountered= true;
        }
        else {
          
            // If that NULL node is not the last node then
            // return false
            if (nullEncountered == true) {
                return false;
            }
          
            // Push both nodes even if 
          	// there are null
            q.push(curr->left);
            q.push(curr->right);
        }      
    }

    return true;
}

int main() {
 
    Node* root = new Node(4);
    root->left = new Node(2);
    root->right = new Node(9);
    
    if (isCompleteBT(root)) {
        cout << "true" << endl;
    } 
    else {
        cout << "false" << endl;
    }

    return 0;
}
Java
import java.util.Queue;
import java.util.LinkedList;

class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

public class Main {
    public static boolean isCompleteBT(Node root) {
        if (root == null) {
            return true;
        }

        Queue<Node> q = new LinkedList<>();
        q.add(root);
        boolean nullEncountered = false;

        while (!q.isEmpty()) {
            Node curr = q.poll();

            if (curr == null) {
                // If we have seen a NULL node, we 
                // set the flag to true
                nullEncountered = true;
            }
            else {
                // If that NULL node is not the last node then
                // return false
                if (nullEncountered == true) {
                    return false;
                }
                // Push both nodes even if 
                // there are null
                q.add(curr.left);
                q.add(curr.right);
            }
        }

        return true;
    }

    public static void main(String[] args) {
        Node root = new Node(4);
        root.left = new Node(2);
        root.right = new Node(9);

        if (isCompleteBT(root)) {
            System.out.println("true");
        }
        else {
            System.out.println("false");
        }
    }
}
Python
from collections import deque

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None


class Solution:
    def isCompleteBT(self, root):
        if root is None:
            return True

        q = deque([root])
        null_encountered = False

        while q:
            curr = q.popleft()

            if curr is None:
                # A NULL position has been found
                null_encountered = True
            else:
                # Non-NULL node after a NULL position
                if null_encountered:
                    return False

                q.append(curr.left)
                q.append(curr.right)

        return True


if __name__ == "__main__":
    root = Node(4)
    root.left = Node(2)
    root.right = Node(9)

    ob = Solution()
    print(str(ob.isCompleteBT(root)).lower())
C#
using System;
using System.Collections.Generic;

public class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

public class Program {
    public static bool isCompleteBT(Node root) {
        if (root == null) {
            return true;
        }

        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);
        bool nullEncountered = false;

        while (q.Count > 0) {
            Node curr = q.Dequeue();

            if (curr == null) {
                // If we have seen a NULL node, we 
                // set the flag to true
                nullEncountered = true;
            }
            else {
                // If that NULL node is not the last node then
                // return false
                if (nullEncountered == true) {
                    return false;
                }
                // Push both nodes even if 
                // there are null
                if (curr.left!= null) {
                    q.Enqueue(curr.left);
                }
                if (curr.right!= null) {
                    q.Enqueue(curr.right);
                }
            }
        }

        return true;
    }

    public static void Main() {
        Node root = new Node(4);
        root.left = new Node(2);
        root.right = new Node(9);

        if (isCompleteBT(root)) {
            Console.WriteLine("true");
        }
        else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

class Solution {
    isCompleteBT(root) {
        if (root === null) {
            return true;
        }

        let q = [root];
        let nullEncountered = false;

        while (q.length > 0) {
            let curr = q.shift();

            if (curr === null) {
                // A NULL position has been found
                nullEncountered = true;
            } else {
                // Non-NULL node after a NULL position
                if (nullEncountered) {
                    return false;
                }

                q.push(curr.left);
                q.push(curr.right);
            }
        }

        return true;
    }
}

// Driver code
let root = new Node(4);
root.left = new Node(2);
root.right = new Node(9);

let ob = new Solution();
console.log(ob.isCompleteBT(root));

Output
true
Comment