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;
}

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

运行结果

相关推荐
Fanxt_Ja19 小时前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下19 小时前
最终的信号类
开发语言·c++·算法
echoarts19 小时前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix20 小时前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题20 小时前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
今后12320 小时前
【数据结构】二叉树的概念
数据结构·二叉树
伍哥的传说20 小时前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔21 小时前
【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔21 小时前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
liujing1023292921 小时前
Day03_刷题niuke20250915
c语言