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)

大概的结构

cpp 复制代码
		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的值会改变(依据队头的值进行调整)

cs 复制代码
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL) 
			break;

		QueuePush(&q,front->left);
		QueuePush(&q,front->right);
	}

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

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

cpp 复制代码
BTNode* front = QueueFront(&q);
while (1)
{
	front = QueueFront(&q);
	QueuePop(&q); 
	if (front == NULL)
	{
		break;
	}
	QueuePush(&q, front->left);
	QueuePush(&q, front->right);
}
cpp 复制代码
	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也入队,因此不存在队列为空的情况

完整代码

cpp 复制代码
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写入

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

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

运行结果

相关推荐
萧瑟余晖10 分钟前
Hibernate 核心原理与架构详解
开发语言·架构·hibernate
爱喝水的鱼丶10 分钟前
SAP-ABAP:SAP MM 模块物料主数据批量导入与增强开发:字段扩展、校验逻辑与批量导入工具开发
开发语言·性能优化·sap·abap·增强·经验交流·mm
geovindu15 分钟前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
susplus20 分钟前
【传感器DS18B20】51单片机上实现温度采集
c语言·51单片机·ds18b20·温度采集
白远山23 分钟前
健身场馆无人自动化解决方案:从架构到落地实践
java·开发语言·数据库·数据挖掘·需求分析
xxwxx__1 小时前
C++ STL set 与 map 全套详解:关联式容器、红黑树底层、代码坑点、刷题实战
数据结构·c++
Data_Journal1 小时前
如何将网页抓取用于机器学习
大数据·开发语言·数据库·python·scrapy
程曦曦1 小时前
MySQL 生产库误删 98 张表后的时间点恢复实战:从 binlog 解析到资金对账
linux·数据结构·其他·算法·ubuntu·运维开发
郝学胜-神的一滴2 小时前
Effective Python 条款 13:善用星号解包,告别下标切片拆分的坑
服务器·开发语言·数据结构·python·程序人生·pycharm
一水鉴天2 小时前
词、术语、概念:从特征集收束到统一拓扑变换的升格与降格模型 20260915(豆包)
开发语言·人工智能