判断是不是完全二叉树(C++)

目录

[1 问题描述](#1 问题描述)

[1.1 示例1](#1.1 示例1)

[1.2 示例2](#1.2 示例2)

[1.3 示例3](#1.3 示例3)

[2 解题思路](#2 解题思路)

[3 代码实现](#3 代码实现)

[4 代码解析](#4 代码解析)

[4.1 定义队列,初始化根节点](#4.1 定义队列,初始化根节点)

[4.2 层序遍历,处理每个节点](#4.2 层序遍历,处理每个节点)

[4.3 处理空节点](#4.3 处理空节点)

[4.4 处理非空节点](#4.4 处理非空节点)

[5 总结](#5 总结)


1 问题描述

给定一个二叉树,确定他是否是一个完全二叉树。

完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)

数据范围:节点数满足 1≤n≤100 1≤n≤100

样例图1:

样例图2:

样例图3:

1.1 示例1

输入:

复制代码
{1,2,3,4,5,6}

返回值:

复制代码
true

1.2 示例2

输入:

复制代码
{1,2,3,4,5,6,7}

返回值:

复制代码
true

1.3 示例3

输入:

复制代码
{1,2,3,4,5,#,6}

返回值:

复制代码
false

2 解题思路

采用层序遍历(BFS)方式,通过队列 queue<TreeNode*> 进行逐层扫描。首先将根节点入队,然后依次出队检查其左右子节点。关键在于一个布尔变量 mustBeLeaf,用于标识是否已经遇到 nullptr,即是否应该只允许叶子节点(空节点)出现。当 nullptr 出现后,若后续仍有非空节点,则说明该树不是完全二叉树,返回 false;否则,遍历结束返回 true。这样保证了若某层的节点不满,则该层之后不能再有非空节点,从而正确判断完全二叉树的性质。

3 代码实现

cpp 复制代码
    bool isCompleteTree(TreeNode* root) {
        // write code here
        if (root == nullptr) return true;
        queue<TreeNode*> q;
        q.push(root);
        bool mustBeLeaf = false;
        while (!q.empty()) {
            TreeNode* node = q.front();
            q.pop();

            if (mustBeLeaf)
            {
                if (node != nullptr) return false;
            }
            else {
                if (node == nullptr)
                {
                    mustBeLeaf = true;
                }
                else {
                    q.push(node->left);
                    q.push(node->right);
                }
            }
        }
        return true;
    }

4 代码解析

4.1 定义队列,初始化根节点

cpp 复制代码
if (root == nullptr) return true;
queue<TreeNode*> q;
q.push(root);
bool mustBeLeaf = false;

首先,代码检查根节点是否为空,若为空,则直接返回 true,因为空树是完全二叉树。然后,定义一个队列 q,用于进行层序遍历(BFS),并将根节点 root 入队。变量 mustBeLeaf 用于标记是否遇到了空节点,一旦为 true,后续所有节点必须为空,否则就不是完全二叉树。

4.2 层序遍历,处理每个节点

cpp 复制代码
while (!q.empty()) {
    TreeNode* node = q.front();
    q.pop();

使用 while 循环进行层序遍历,每次从队列 q 中取出队首节点 node。如果 q 为空,说明遍历完成,跳出循环。

4.3 处理空节点

cpp 复制代码
    if (mustBeLeaf)
    {
        if (node != nullptr) return false;
    }

如果 mustBeLeaftrue,说明之前已经遇到了空节点,那么所有后续节点都必须为空。如果当前节点 node 不是空节点,则说明二叉树不是完全二叉树,直接返回 false

4.4 处理非空节点

cpp 复制代码
    else {
        if (node == nullptr)
        {
            mustBeLeaf = true;
        }
        else {
            q.push(node->left);
            q.push(node->right);
        }
    }

如果 mustBeLeaf 仍为 false,则说明当前节点还可以是非空的。如果当前节点 nodenullptr,则将 mustBeLeaf 设为 true,意味着之后所有节点必须为空。如果当前节点 node 不是 nullptr,则继续将 node->leftnode->right 依次入队,即继续层序遍历子节点。

5 总结

通过队列依次遍历每个节点,并使用布尔变量 mustBeLeaf 来标记是否已经遇到空节点,确保一旦出现 nullptr,后续所有节点都必须为空,否则返回 false。该方法能有效检测是否存在不连续的叶子节点,从而正确判断完全二叉树的性质。整个算法的时间复杂度为 O(n) ,空间复杂度为 O(n) ,适用于 n ≤ 100 的数据范围,能够高效解决问题。

相关推荐
CYRUS_STUDIO1 小时前
Android 自定义变形 MD5 算法
android·算法·安全
menge23333 小时前
Python递归与递推的练习(初步了解复杂度,全排列的价值,奇妙的变换,数正方形,高塔登顶方案)
算法
Vitalia3 小时前
⭐算法OJ⭐二叉树的后序遍历【树的遍历】(C++实现)Binary Tree Postorder Traversal
开发语言·c++·算法·二叉树
LCY1333 小时前
数据库与其所用数据结构
数据结构·数据库
飞鼠_3 小时前
c++简单实现redis
c++·redis·bootstrap
做一个码农都是奢望4 小时前
MATLAB 调用arduino uno
开发语言·算法·matlab
二进制人工智能4 小时前
【QT5 多线程示例】互斥锁
开发语言·c++·qt
沈阳信息学奥赛培训4 小时前
C++语法之命名空间二
开发语言·c++·算法
猪猪成4 小时前
【FLOYD+并查集】蓝桥杯算法提高 Degrees of Separation
算法·图论
Dust-Chasing5 小时前
数据结构之顺序表和栈
c语言·数据结构·算法