如何判断一个树是否为完全二叉树
完全二叉树,叶子节点只会出现最后2层,且最后1层的叶子节点都靠左对齐
或者
一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
用程序判断的大概思路:
如果树为空,则返回false
如果树不为空,则层序遍历该二叉树:
如果该节点的左右子节点都不为空,则入队。
如果该节点的左子节点为空,右子节点不为空,则一定不是完全二叉树
如果该节点的左子节点不为空,右子节点为空;或者左右子节点都为空,那么之后的节点都是叶子节点,则是完全二叉树。否则不是完全二叉树。
也就是2*2=4种状态的组合。
public static boolean isCompleteBinaryTree(TreeNode root)
{
if(root == null) return false;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
boolean leaf = false;
while(!queue.isEmpty()) {
TreeNode node = queue.poll();
//最后一种情况,需要之后的节点都是叶子节点
if(leaf && !(node.left == null && node.right == null))//如果此时需要是叶子节点,但并不是叶子节点,则返回false
{
return false;
}
//四种情况:00 01 10 11
if(node.left != null && node.right != null) {//11
queue.add(node.left);
queue.add(node.right);
}else if(node.left == null && node.right != null) {//01
return false;
}else {//00和10都是叶子节点
leaf = true;
if(node.left != null) {
queue.add(node.left);
}
}
}
return true;
}
或者:
如果树为空,则返回false
如果树不为空,则层序遍历该二叉树:
如果该节点的左子节点不为空,则左子节点入队。
如果该节点的左子节点为空,右子节点不为空,则一定不是完全二叉树
如果该节点的右子节点不为空,则右子节点入队。
如果该节点的右子节点为空(左子节点为空 或者 左子节点不为空),那么之后的节点都是叶子节点,则是完全二叉树。否则不是完全二叉树。
public static boolean isCompleteBinaryTree(TreeNode root)
{
if(root == null) return false;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
boolean leaf = false;
while(!queue.isEmpty()) {
TreeNode node = queue.poll();
if(leaf && !(node.left == null && node.right == null))//如果此时需要是叶子节点,但并不是叶子节点,则返回false
{
return false;
}
if(node.left != null) {
queue.add(node.left);
}else if(node.right != null) {//node.left == null && node.right != null
return false;
}
if(node.right != null) {
queue.add(node.right);
}else {
//node.left == null && node.right == null
//node.left != null && node.right == null;
leaf = true;
}
}
return true;
}