当前位置: 首页 > news >正文

110.【C语言】数据结构之判断是否为完全二叉树

目录

1.知识回顾

2.分析

完全二叉树队列示意图

 非完全二叉树队列示意图

区别

3.代码

执行过程

完整代码

运行结果


1.知识回顾

完全二叉树和非完全二叉树参见100.【C语言】数据结构之二叉树的基本知识文章

2.分析

使用层序遍历(队列),核心思想参见109.【C语言】数据结构之二叉树层序遍历文章

这里对比完全二叉树和非完全二叉树在层序遍历中的区别

注意:和以往的层序遍历有所不同,空节点也要push(push它的地址NULL)

完全二叉树队列示意图

 非完全二叉树队列示意图

区别

当两个队列的队头为NULL时,观察两个队列之间的区别

完全二叉树:元素全为空

非完全二叉树:有非空元素

可以此来判断是否为完全二叉树

3.代码

执行过程

初始化队列-->非空树,将根节点的地址入队-->层序遍历+出栈+入栈-->对队头的值判断(为NULL则一直出队,遇到非空则销毁队列+返回false)

层序遍历+出栈+入栈

根节点出栈,出栈前需要保留根节点的地址,以便于左右节点入栈(front->left和front->right,不是root->left和root->right)

大概的结构

		BTNode* front = QueueFront(&q);QueuePop(&q);QueuePush(&q,front->left);QueuePush(&q,front->right);

疑问1:不是对根节点的左右节点入栈吗?为什么不写成root->left和root->right呢?
root一直是整个二叉树根节点的地址,导致root->left和root->right的值一直没有变化,导致死循环

如果写成front->left和front->right,每次循环时,front的值会改变(依据队头的值进行调整)

	while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);if (front == NULL) break;QueuePush(&q,front->left);QueuePush(&q,front->right);}

最终当队头为NULL时,退出循环

疑问2:第一个while的部分能写成下面这两种吗?

BTNode* front = QueueFront(&q);
while (1)
{front = QueueFront(&q);QueuePop(&q); if (front == NULL){break;}QueuePush(&q, front->left);QueuePush(&q, front->right);
}
	while (QueueFront(&q)){BTNode*  front = QueueFront(&q);QueuePop(&q); if (front == NULL){break;}QueuePush(&q, front->left);QueuePush(&q, front->right);}

两种写法均可以,while循环退出的唯一出口在if (front==NULL),由于NULL也入队,因此不存在队列为空的情况

完整代码

bool TreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);if (front == NULL) break;QueuePush(&q,front->left);QueuePush(&q,front->right);}while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);if (front){QueueDestroy(&q);return false;}}QueueDestroy(&q);return true;	
}

注意返回前养成好习惯,需要销毁队列

main.c写入

int main()
{BTNode* root = CreateTree();printf("TreeComplete:%d", TreeComplete(root));return 0;
}

备注:创建的二叉树的结构为

运行结果


http://www.mrgr.cn/news/79971.html

相关文章:

  • c#动态更新替换json节点
  • 【开源】基于SpringBoot框架的在线视频教育平台 (计算机毕业设计)+万字毕业论文 T027
  • CentOS8或docker镜像centos8更换镜像源
  • C++ webrtc开发(非原生开发,linux上使用libdatachannel库)
  • T0怎么做?程序化T0增加持仓收益!
  • JAVA基础-深入理解Java内存模型(一)-- 重排序与先行发生原则(happens-before)
  • erlang 基于jose 实现 aes 加解密
  • 【C++】判断能否被 3, 5, 7 整除问题解析与优化
  • WIN11中安装Mamba常见问题解决方案
  • windows C#-自动实现属性的轻型类
  • Java项目实战II基于Java+Spring Boot+MySQL的社区帮扶对象管理系统的设计与实现(开发文档+数据库+源码)
  • src 和 href 的区别
  • 在AMD Instinct MI300X加速器上训练Transformers和混合模型
  • 深入解析C++中的函数指针与`typedef`的妙用
  • 快速上手Neo4j图关系数据库
  • 测试岗位应该学什么
  • 操作系统(3)操作系统的运行环境
  • 【他山之石】Leading-Trim: The Future of Digital Typesetting:数字排版的未来 —— Leading-Trim
  • 文献分享: PLAID——为ColBERT架构设计的后期交互驱动器
  • 【qt环境配置】windows下的qt与vs工具集安装\版本对应关系
  • 常见LeetCode-Saw200
  • C#,人工智能,深度学习,目标检测,OpenCV级联分类器数据集的制作与《层级分类器一键生成器》源代码
  • 黑马头条学习笔记
  • 【JVM】JVM基础教程(三)
  • 第 8 章 对象、类与面向对象编程
  • L0、L1与L2范数、核范数