数据结构之判断完全二叉树详解与示例(C,C++)

文章目录

    • 一、判断完全二叉树的思路
    • 二、C语言实现
    • 三、C++语言实现
    • 四、总结

在这里插入图片描述


完全二叉树是一种特殊的二叉树,它满足以下两个条件:

每一层(除了最后一层)都被严格地填充了节点。
最后一层的节点都尽可能地靠左对齐。
本文将详细介绍如何判断一个二叉树是否为完全二叉树,并提供C和C++的实现示例。

一、判断完全二叉树的思路

我们可以通过层序遍历(广度优先搜索)的方式来判断一个二叉树是否为完全二叉树。在层序遍历过程中,我们遵循以下步骤:

  1. 如果当前节点有左子树和右子树,则将它们分别加入队列。
  2. 如果当前节点只有左子树,没有右子树,则将左子树加入队列,并在之后的遍历中,所有节点都必须是叶子节点。
  3. 如果当前节点没有子树,则该节点之后的所有节点都必须是叶子节点。
  4. 如果在遍历过程中,出现了不符合上述条件的节点,那么该二叉树就不是完全二叉树。

二、C语言实现

以下是C语言的实现示例:

#include <stdio.h>
#include <stdlib.h>// 定义二叉树节点结构体
typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;
} TreeNode;// 判断二叉树是否为完全二叉树
int isCompleteBinaryTree(TreeNode *root) {if (root == NULL) return 1; // 空树也是完全二叉树// 初始化队列TreeNode *queue[10000];int front = 0, rear = 0;queue[rear++] = root;// 开始层序遍历while (front < rear) {TreeNode *cur = queue[front++];// 如果遇到空节点,判断后续节点是否都是空节点if (cur == NULL) {while (front < rear) {if (queue[front] != NULL) return 0;front++;}} else {// 将左右子树加入队列queue[rear++] = cur->left;queue[rear++] = cur->right;}}return 1; // 遍历完成,没有发现不符合条件的节点,是完全二叉树
}// 创建节点
TreeNode* createNode(int val) {TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode));node->val = val;node->left = NULL;node->right = NULL;return node;
}int main() {// 创建一个示例二叉树TreeNode *root = createNode(1);root->left = createNode(2);root->right = createNode(3);root->left->left = createNode(4);root->left->right = createNode(5);// 判断是否为完全二叉树if (isCompleteBinaryTree(root)) {printf("该二叉树是完全二叉树。\n");} else {printf("该二叉树不是完全二叉树。\n");}return 0;
}

三、C++语言实现

以下是C++的实现示例:

#include <iostream>
#include <queue>using namespace std;// 定义二叉树节点结构体
struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};// 判断二叉树是否为完全二叉树
bool isCompleteBinaryTree(TreeNode* root) {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; // 遍历完成,没有发现不符合条件的节点,是完全二叉树
}int main() {// 创建一个示例二叉树TreeNode *root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);// 判断是否为完全二叉树if (isCompleteBinaryTree(root)) {cout << "该二叉树是完全二叉树。" << endl;} else {cout << "该二叉树不是完全二叉树。" << endl;}return 0;
}

四、总结

通过上述C和C++的实现示例,我们可以看到判断一个二叉树是否为完全二叉树的基本方法是使用层序遍历。在遍历过程中,我们通过设置一个标记来区分节点是否应该为叶子节点,从而判断二叉树是否满足完全二叉树的条件。这种方法的时间复杂度为O(n),其中n是二叉树中节点的数量,因为每个节点最多只会被访问一次。

在实际应用中,完全二叉树由于其特殊的结构,常用于堆的实现,因为它可以在数组中有效地表示,同时保持堆的操作效率。理解并掌握判断完全二叉树的方法,对于深入理解二叉树结构和相关算法有重要意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/49422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

undefined reference to rpl_malloc

编译 psmisc 时遇到这个错误&#xff0c;搜索了一下 rpl_malloc&#xff0c; grep -irwn rpl_malloc config.status:877:D["malloc"]" rpl_malloc" Binary file src/killall.o matches autom4te.cache/traces.1:979:m4trace:configure.ac:205: -1- AH_OUT…

微服务(网关路由)

目录 一&#xff1a;网关路由 1&#xff1a;认识网关 2&#xff1a;快速入门 2.1&#xff1a;创建项目 2.2&#xff1a;引入依赖 2.3&#xff1a;启动类 2.4&#xff1a;路由配置 2.5&#xff1a;测试 3&#xff1a;路由过滤 二&#xff1a;网关登录校验 1&…

58、主从复制数据库+读写分离

mysql的主从复制和读写分离&#xff08;面试问原理&#xff09; mysql的主从复制和读写分离&#xff1a; 主从复制 面试必问 主从复制的原理。 读写分离&#xff0c;MHA 一、主从复制 1.1、主从复制的模式&#xff1a; 1、mysql的默认模式&#xff1a; 异步模式&#xf…

RocketMQ集群搭建,看完这篇文章你就懂了(基于2m-2s-async模式)

前言 上一篇初步认识了RocketMQ&#xff0c;这一篇文章我们简单来搭建一个RocketMQ集群。RocketMQ支持多种集群部署模式&#xff0c;其中最常用的是多主多从的异步复制模式&#xff08;2m代表两个master&#xff0c;2s代表两个slave&#xff0c;async代表异步刷盘的机制&#…

java将网址生成二维码图片base64

1、pom中引入组件 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version> </dependency> 2、代码实现 // 生成二维码public String jumpToQRcodeGen(String url) {int wi…

乐鑫ESP32-H2设备联网芯片,集成多种安全功能方案,启明云端乐鑫代理商

在数字化浪潮的推动下&#xff0c;物联网正以前所未有的速度融入我们的日常生活。然而&#xff0c;随着设备的激增&#xff0c;安全问题也日益成为公众关注的焦点。 乐鑫ESP32-H2致力于为所有开发者提供高性价比的安全解决方案&#xff0c;这款芯片经过专门设计以集成多种安全…

[Armbian] 部署Docker版Home Assistent,安装HACS并连接米家设备

title: [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 date: 2024-07-21T10:51:23Z lastmod: 2024-07-21T11:40:39Z [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 官网&#xff1a;Home Assistant (home-assistant.i…

git -.gitignore不生效的问题

目录 1&#xff0c;问题场景2&#xff0c;原因3&#xff0c;解决单个文件文件夹 1&#xff0c;问题场景 1&#xff0c;当执行 git add . 命令后&#xff0c;才想起来部分文件需要被忽略不上传&#xff0c;这时加到 .gitignore 中发现不生效&#xff0c;之后的 git commit 依旧…

FoundationDB 基本使用

目录 一、FoundationDB介绍 二、安装单机版FoundationDB 2.1 下载安装程序 2.2 安装FoundationDB 2.3 修改配置信息 2.4 管理FoundationDB服务 三、fdbcli的常用命令 3.1连接数据库 3.2退出fdbcli 3.3查看版本 3.4 写模式 3.5写入键值 3.6读取键值 3.7删除键值 …

Unity3D中Instance创建实例问题详解

前言 在Unity3D开发中&#xff0c;对象的创建和管理是一个基础且重要的环节。Instance&#xff08;实例&#xff09;和Singleton&#xff08;单例&#xff09;是两种常见的对象创建方式&#xff0c;它们在Unity3D中有不同的应用场景和实现方法。本文将详细解析Unity3D中如何通…

无法连接到internet怎么办?已连接但无internet访问,其实并不难

有时我们会遇到无法连接到Internet的问题&#xff0c;由多种原因引起&#xff0c;包括硬件故障、软件设置问题、网络供应商故障等。本文将介绍无法连接到Internet时可以采取的步骤。 简述 当你无法连接到Internet时&#xff0c;可以按照以下步骤进行检查和解决&#xff1a; 1…

python实现特征检测算法4

python实现Richardson-Lucy 反卷积算法 Richardson-Lucy 反卷积算法算法原理Python实现详细解释Richardson-Lucy算法的优缺点应用领域Richardson-Lucy 反卷积算法 Richardson-Lucy反卷积算法是一种迭代算法,用于恢复因成像系统中的点扩散函数(PSF)导致的模糊图像。该算法最…

TCP系列(一)-介绍TCP

服务 TCP和UDP同样使用IP提供的服务&#xff0c;但是TCP提供的是面向连接&#xff0c;可靠的字节流服务 面向连接 使用TCP进行通信双方&#xff0c;必须先建立连接&#xff0c;然后进行数据交换 可靠服务 将应用数据分割成固定大小的报文段每次发出报文&#xff0c;会启动定时…

分享从零开始学习网络设备配置--任务6.1 实现计算机的安全接入

项目描述 随着网络技术的发展和应用范围的不断扩大&#xff0c;网络已经成为人们日常生活中必不可少的一部分。园区网作为给终端用户提供网络接入和基础服务的应用环境&#xff0c;其存在的网络安全隐患不断显现出来&#xff0c;如非人为的或自然力造成的故障、事故&#xff1b…

昇思25天学习打卡营第09天|使用静态图加速

MindSpore支持两种运行模式&#xff1a;动态图&#xff08;PyNative模式&#xff09;和静态图&#xff08;Graph模式&#xff09;。 动态图模式下&#xff0c;计算图的构建和计算同时发生&#xff0c;适合调试和开发&#xff0c;但不利于优化。 静态图模式下&#xff0c;计算…

【概率论】-2-概率论公理(Axioms of Probability)

上一篇文章我们学习了基本的概率论内容-排列组合&#xff0c;本次我们学习概率论公理的内容&#xff0c;正式开始计算概率&#xff0c;在开始前我们需要学习一些基本概念。 目录 一.样本空间和事件 1.样本空间 2.事件 3.交并补 二、概率公理 1.基本公理 2.对称差 2.布尔…

vuex的工作流程,模块化使用案例分享,及状态持久化

文章目录 一、Vuex 是什么&#xff1f;二、核心概念三、Vuex 的工作流程四、什么情况下我应该使用 Vuex&#xff1f;五、Vuex 的使用六、使用示例七、状态持久化1、手动利用HTML5的本地存储2、利用vuex-persistedstate插件2.1、安装2.2、配置 一、Vuex 是什么&#xff1f; Vue…

[C++]类的自动转换和强制类型转换

在C中&#xff0c;类的自动转换&#xff08;也称为隐式转换&#xff09;和强制类型转换&#xff08;显式转换&#xff09;是面向对象编程中处理类型之间转换的两种重要机制。这些转换允许程序员定义如何在不同类型&#xff08;特别是自定义类型&#xff09;之间安全地交换数据。…

USART串口理论知识总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 USART串口理论知识总结 1、通讯的串行和并行1.串口采用发送数据代码并用printf重代码 1、通讯的串行和并行 1.串口采用发送数据代码并用printf重代码 #include <stdint.h…

Reator模型

文章目录 概述Reacotr模型&#xff1a;定义特点三个重要组件具体流程Reactor优点应用场景 代码片段 小结 概述 Reactor模型是一种设计模式&#xff0c;主要用于处理并发的I/O事件&#xff0c;特别是在网络编程和服务器设计中。 Reacotr模型&#xff1a; 定义 Reactor模式是…