前言
本文将介绍什么是完全二叉树、满二叉树以及如何判断一棵二叉树是否为完全二叉树、满二叉树。
完全二叉树
先来看一下什么是完全二叉树。
完全二叉树的每一层都是满的,如果有一层不满的话也是最后一层不满,即使最后一层不满也是从左到右依次变慢的过程。这个满是指满二叉树,也就是一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
逐渐变满是指中间不能跳过空位,也就是一个节点不能只有右节点。
如果只有一个节点,那么这个节点也是完全二叉树,因为一个节点也是满的。
如下图几个都是完全二叉树,因为每一层都是满的,或者从左到右正在逐渐变满。
判断方法
完全二叉树的遍历方式需要按层进行遍历,从上往下一层一层的进行遍历。
在按层遍历二叉树时,判断是否为完全二叉树需要遵循以下原则:
- 如果一个节点,只有右子节点,那么这颗二叉树肯定不是完成二叉树,可以直接返回
false。 - 当遇到第一个节点不是左右不双全时,那么剩下的节点必须是叶子节点。
只要都满足以上条件,那么一个二叉树就是完全二叉树,任何一点不满足的话,就不是完全二叉树。
之前有一篇文章介绍过如何按层遍历一棵二叉树,这里就不再赘述了,有兴趣的小伙伴可以参考这篇文章juejin.cn/post/722375…
代码实现
下面来看下判断是否为完全二叉树的代码,代码如下:
public class Node {
public int value;
public Node left;
public Node right;
}
public boolean isCBT(Node head) {
if (head == null) {
return true;
}
LinkedList<Node> queue = new LinkedList<>();
// 是否遇到过左右两个孩子不双全的节点
boolean leaf = false;
Node l = null;
Node r = null;
queue.add(head);
while (!queue.isEmpty()) {
head = queue.poll();
l = head.left;
r = head.right;
if ((leaf && (l != null || r != null)) || (l == null && r != null)) {
return false;
}
if (l != null) {
queue.add(l);
}
if (r != null) {
queue.add(r);
}
if (l == null || r == null) {
leaf = true;
}
}
return true;
}
在代码中有一个比较重要的if判断:
l == null && r != null是指如果一个节点只有右节点,肯定不是完全二叉树(leaf && (l != null || r != null)是指,如果之前遍历遇到过左右不相等的节点,那么其他节点的左右节点都必须为null,否则的话就不是完全二叉树。
满二叉树
再来看一下满二叉树的定义:
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。从树的高度上来说,如果一棵树的高度为k,那么这棵二叉树的总结点数为2k - 1,满足这样性质的二叉树就为满二叉树。
如下图所示,下面的两棵树都是满二叉树。
判断方法
判断一个树是否为满二叉树有多种方法:
方法一
可以先计算出二叉树的高度以及二叉树的节点数,判断是否满足满二叉树的节点数即可。
方法二
可以利用递归的方式,判断子节点是否是满二叉树,如果都满足满二叉树,那么这棵树就为满二叉树。
代码实现
这里根据方法一的判断思路来判断下,一棵二叉树是否为满二叉树。
public boolean isFull(Node head) {
if (head == null) {
return true;
}
Info all = process(head);
return (1 << all.height) - 1 == all.nodes;
}
public class Info {
public int height;
public int nodes;
public Info(int height, int nodes) {
this.height = height;
this.nodes = nodes;
}
}
public Info process(Node head) {
if (head == null) {
return new Info(0, 0);
}
Info leftInfo = process(head.left);
Info rightInfo = process(head.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int nodes = leftInfo.nodes + rightInfo.nodes + 1;
return new Info(height, nodes);
}
总结
本文将介绍什么是完全二叉树、满二叉树以及如何判断一棵二叉树是否为完全二叉树、满二叉树,如有收获就帮忙点个赞吧~