判断是否为完全二叉树、满二叉树

780 阅读3分钟

前言

本文将介绍什么是完全二叉树、满二叉树以及如何判断一棵二叉树是否为完全二叉树、满二叉树。

完全二叉树

先来看一下什么是完全二叉树。

完全二叉树的每一层都是满的,如果有一层不满的话也是最后一层不满,即使最后一层不满也是从左到右依次变慢的过程。这个满是指满二叉树,也就是一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。

逐渐变满是指中间不能跳过空位,也就是一个节点不能只有右节点。

如果只有一个节点,那么这个节点也是完全二叉树,因为一个节点也是满的。

如下图几个都是完全二叉树,因为每一层都是满的,或者从左到右正在逐渐变满。

判断方法

完全二叉树的遍历方式需要按层进行遍历,从上往下一层一层的进行遍历。

在按层遍历二叉树时,判断是否为完全二叉树需要遵循以下原则:

  • 如果一个节点,只有右子节点,那么这颗二叉树肯定不是完成二叉树,可以直接返回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);
}

总结

本文将介绍什么是完全二叉树、满二叉树以及如何判断一棵二叉树是否为完全二叉树、满二叉树,如有收获就帮忙点个赞吧~