完全二叉树:
对于一个树高为h的二叉树,如果其第0层至第h-1层的节点都满。如果最下面一层节点不满,则所有的节点在左边的连续排列,空位都在右边。这样的二叉树就是一棵完全二叉树。
思路:
- 任何一个结点如果右孩子不为空,左孩子却是空,则一定不是完全二叉树
- 当一个结点出现右孩子为空时候,判断该结点的层次遍历后继结点是否为叶子节点,如果全部都是叶子节点,则是完全二叉树,如果存在任何一个结点不是叶节点,则一定不是完全二叉树。
实现:
//节点类型定义
class BtNode{
int value;
BtNode left;
BtNode right;
public BtNode(int value) {
this.value = value;
}
}
//具体实现
public boolean Is_Comp_Tree(BtNode root)
{
boolean res = true;//如果当前出队列的节点是叶子节点,那么res为true
if(root == null) return res;
Queue<BtNode> qu = new LinkedList<BtNode>();
BtNode leftChild = null;
BtNode rightChild = null;
qu.offer(root);
while(!qu.isEmpty()){
BtNode head = qu.poll();
leftChild = head.left;
rightChild = head.right;
//1.当前出队列的节点的左孩子为null但右孩子不为null,返回false
//2.当前出队列的节点的前一个节点(也就是上一轮while循环出队列的节点)是叶子节点(用res来标记),并且当前出队列的节点有左孩子或右孩子,返回false
if((null != rightChild && null == leftChild)||
(res && (null != rightChild || null != leftChild))
) {
return false;
}
if(leftChild!=null)
{
qu.offer(leftChild);
}
else if(rightChild!=null)
{
qu.offer(rightChild);
}else
{
//如果当前节点的左右孩子都为null,那么当前节点就为叶子节点;
//用res=true记录下来,下一个出队列的节点就不能再有孩子,不然返回false
res = true;
}
}
return true;
}
大家可以看一下注释,其实代码可以更简洁,但是这样写最直观,最方便理解。