如何判断一个二叉树是否为完全二叉树

判断一个二叉树是否为完全二叉树,可以通过层序遍历(广度优先搜索,BFS)的方式来实现。完全二叉树的特点是,除了最后一层外,每一层都被完全填满,并且所有节点都尽可能地向左对齐。在层序遍历过程中,如果遇到某个节点为空(即null或None),则之后遍历到的所有节点都应该为空;如果之后还遍历到了非空节点,则说明该二叉树不是完全二叉树。

以下是一个基于层序遍历判断二叉树是否为完全二叉树的算法步骤(以Python为例):

1、初始化一个队列,并将根节点入队。

2、标记一个标志位is_end为False,用于表示是否遇到了第一个空节点。

3、当队列不为空时,进行循环:

从队列中取出一个节点。

如果该节点为空,并且is_end为False,则将is_end设置为True,表示这是遇到的第一个空节点。

如果该节点不为空,但是is_end已经为True,则说明在第一个空节点之后还存在非空节点,该二叉树不是完全二叉树,直接返回False。

如果节点不为空,则将其左子节点和右子节点(如果存在)依次入队。

4、循环结束后,如果is_end仍然为False,则说明队列中的所有节点都已经被遍历且都非空,但这并不意味着它是完全二叉树(可能是满二叉树)。然而,根据完全二叉树的定义,只要没有违反"在第一个空节点后仍有非空节点"的规则,就可以认为是完全二叉树。因此,在这种情况下,我们也可以认为它是完全二叉树(实际上,这一步是多余的,因为只要没有在第3步返回False,就可以确定它是完全二叉树)。

python 复制代码
from collections import deque

class TreeNode:
    def __init__(self, value=0, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right

def isCompleteTree(root):
    if not root:
        return True  # 空树被认为是完全二叉树

    queue = deque([root])
    is_end = False

    while queue:
        node = queue.popleft()

        if not node:
            is_end = True
            continue

        if is_end:
            return False  # 遇到了第一个空节点之后还有非空节点

        queue.append(node.left)
        queue.append(node.right)

    return True

# 使用示例
# 构建一个完全二叉树
#       1
#      / \
#     2   3
#    / \   \
#   4   5   6
# 注意:这里并没有完全按照完全二叉树的规则来构建(比如节点6的左子树为空),
# 但为了示例,我们假设它是一个"逻辑上"的完全二叉树,即只关注是否存在"在第一个空节点后仍有非空节点"的情况。
# 实际上,在构建二叉树时,我们通常不会显式地创建空节点。
# 下面的代码只是为了演示如何连接节点,并没有真正地创建空节点。
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)

# 调用函数检查
print(isCompleteTree(root))  # 输出: True(在这个特定的"逻辑"下)
相关推荐
写后端的胖头鱼6 小时前
一文详解B+树原理(附场景+示例)
数据结构·b树
阳光九叶草LXGZXJ7 小时前
达梦数据库-报错-15-列【XXX】长度超出定义
linux·运维·数据库·sql·学习
怕浪猫8 小时前
RAG 面试 6 连问,从原理到优化全部覆盖
python·算法·面试
无线通信科研笔记8 小时前
IEEE TVT 2026 论文精读与完整复现|相位误差如何重塑近场 RIS 的幅相响应
论文阅读·人工智能·python·算法·论文笔记
daidaidaiyu8 小时前
ThingsBoard 集群的核心逻辑源码分析
java
mmmmath_39 小时前
二叉树の递归遍历
算法
All for pursuit.9 小时前
【位运算-1】338.比特位计数
数据结构·c++·算法·leetcode
我可能是个假开发9 小时前
FTP Unicode 文件名导致 `550` 的问题分析与解决方案
java·开发语言·spring
caoerzhong10 小时前
中小企业上 WMS 该先上哪几块:JeeWMS 开源 Java 仓库管理系统的分批上线清单
java·python·开源
小师兄吃牛肉10 小时前
C语言中的nullptr有必要吗
c语言·c++·算法