概念
完全二叉树定义:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
分析一下完全二叉树的概念,有几个特点:
1.完全二叉树的概念是在层序遍历的基础上建立的,层序遍历就是从上而下一层层遍历,每层是从左到右遍历。
2.如果有一个节点的左孩子不存在,右孩子却存在,那么必定不是完全二叉树
3.当出现某一个节点的左右孩子不是都存在时,那么这个节点层序遍历后面的所有节点,都是叶子节点。
代码思路
既然完全二叉树是在层序遍历的基础上建立的,那么,判断一颗二叉树是不是完全二叉树,也是用层序遍历来遍历该二叉树最合适。
层序遍历思路:
一层层遍历二叉树,借助一个队列来实现,先将根节点入队列,如果队列不为空,就出队列第一个节点,并且把该节点的左右孩子依次入队列,依次循环,直到队列为空。
判断完全二叉树:
用层序遍历二叉树,根据上面二叉树的第三个特点,设定一个boolean类型的标志变量,判断是否出现某个节点孩子缺失的情况,然后标志变量改变,从此后所有节点都是叶子节点。判断是否出现孩子节点缺失时,一共有四种情况:
1.两个孩子都缺失,标志变量改变。
2.两个孩子都不缺失,依次按照从左到右入队列,继续遍历。
3.右孩子缺失,标志变量改变。
4.左孩子缺失,右孩子不缺少,此时是上面第二个特点,可以直接判断不是完全二叉树。
代码
public static boolean isCBT(TreeNode node){
if(node==null){
return true;
}
Queue<TreeNode> queue = new LinkedList<>();
boolean leaf=false;
queue.offer(node);
while (!queue.isEmpty()){
node=queue.poll();
TreeNode l=node.left;
TreeNode r=node.right;
if(leaf){
if(l!=null||r!=null){
return false;
}
}else {
if(l==null&&r!=null){
return false;
}else if(l==null&&r==null){
leaf=true;
}else if(l!=null&&r==null){
queue.offer(l);
leaf=true;
}else {
queue.offer(l);
queue.offer(r);
}
}
}
return true;
}