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

devtools/2025/3/29 22:22:26/

目录

1 问题描述

1.1 示例1

1.2 示例2

1.3 示例3

2 解题思路 

3 代码实现

4 代码解析

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

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

4.3 处理空节点

4.4 处理非空节点

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 代码实现

    bool isCompleteTree(TreeNode* root) {// write code hereif (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 定义队列,初始化根节点

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

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

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

while (!q.empty()) {TreeNode* node = q.front();q.pop();

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

4.3 处理空节点

    if (mustBeLeaf){if (node != nullptr) return false;}

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

4.4 处理非空节点

    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 的数据范围,能够高效解决问题。


http://www.ppmy.cn/devtools/171244.html

相关文章

学习记录-Ajax-自封装axios函数

目录 自封装axios函数封装axios函数实现步骤1. 准备阶段2. 实现无参get请求3.实现有参get请求4. 实现post请求 完整实例代码 自封装axios函数 封装axios函数实现步骤 1. 准备阶段 理解axios函数的底层原理&#xff0c;包括Promise,XMLHttpRequest等概念 XMLHttpRequest工作…

贪心算法(11)(java)加油站

题目&#xff1a;在一条环路上有n个加油站&#xff0c;其中第i个加油站有汽油 gas[i]升.。 你有一辆油箱容量无限的的汽车&#xff0c;从第i个加油站开往第i1个加油站需要消耗汽油 cost[i]升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定…

Spring Security核心源码和功能实现

Spring Security 是一个强大的安全框架,用于保护基于 Spring 的应用程序。它提供了认证、授权、防止常见安全攻击等功能。下面是对 Spring Security 的核心功能和实现的详细分析,并使用 Mermaid 绘制相关流程图。 1. 核心功能 1.1 认证(Authentication) 用户认证:验证用…

【41】单片机编程核心技巧:const 与 code 的存储优化

【41】单片机编程核心技巧&#xff1a;const 与 code 的存储优化 七律 存储优化 常量存储ROM中&#xff0c;const与code异同。 变量常量分两域&#xff0c;RAM省空间有功。 查表阀值一键改&#xff0c;代码优化显神通。 单片机中精设计&#xff0c;资源管理更从容。 摘要 本…

A l密码学(Deepseek)

我&#xff1a;qwertyuiopasdfghjklzxcvbnm deepseek:深度思考中&#xff0e; Okay, lets see. The user input is "qwertyuiopasdfghjklzxcvbnm". At first glance, it looks like a jumbled sequence of letters with some spaces or maybe other characters in …

数据结构--堆

一&#xff0c;引言 堆作为一种特殊的二叉树类型有这很重要的实现意义&#xff0c;本文不详细堆的堆的感念性问题&#xff0c;注意进行讲解堆算法的实现。 由于堆为完全二叉树中间没有空隙&#xff0c;所以用数组来进行存储&#xff0c;以数组的下标来确认其二叉树各个节点的…

GitHub高级筛选小白使用手册

GitHub高级筛选小白使用手册 GitHub 提供了强大的搜索功能&#xff0c;允许用户通过高级筛选器来精确查找仓库、Issues、Pull Requests、代码等。下面是一些常用的高级筛选用法&#xff0c;帮助你更高效地使用 GitHub 搜索功能。 目录 搜索仓库搜索Issues搜索Pull Requests搜…

扩散语言模型:AI编程的未来

李升伟 整理 随着GPT-4等自回归Transformer模型为AI生成文本树立标杆&#xff0c;语言模型正在快速进化。如今&#xff0c;一类新型模型崭露头角&#xff1a;以Inception Labs的Mercury为代表的扩散语言模型。传统大语言模型&#xff08;LLM&#xff09;逐词生成文本&#xff…