牛客网_NC198.判断是不是完全二叉树

题目描述

给定一个二叉树,确定他是否是一个完全二叉树。

完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)

数据范围:节点数满足1≤n≤100

图示

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

思路分析

要想把这道题做好,首先必须得知道完全二叉树的特点

  1. 完全二叉树的节点个数范围在:[2^ (h-1), 2^h-1]
  2. 完全二叉树是连续不断的
    在这里插入图片描述
    根据这两个特点来想解决办法:

利用完全二叉树范围的特点来判断(错误方法)

有一种思路:可以根据完全二叉树的节点个数来判断是不是完全二叉树,但是看似没问题,实则没办法判断;
因为如果个数达标,但是并不连续,则也不是完全二叉树
如下图:
在这里插入图片描述
在这里插入图片描述
结点个数在完全二叉树的范围之中,但是仍然不是完全二叉树;
所以基本可以判断,利用这个性质是没办法直接判断的

利用完全二叉树连续的特点来判断(正确方法)

因为它是连续的,所以我们可以利用层序遍历的特点来判断

点击此处跳转到层序遍历

如果说层序遍历的结果是这样的【1, 2, 3, 4, 5, NULL,NULL,NULL……】,那么他就是完全二叉树,因为在这个结果中,当出现NULL后就不会再出现数字了
在这里插入图片描述

但如果是这样的:【1, 2, 3, 4, 5,NULL,6, NULL,NULL,NULL……】
那就不是完全二叉树
在这里插入图片描述
所以思路就是:走一遍层序遍历,然后在层序遍历之间加上判断
在这里插入图片描述

样例代码

部分代码(只是判断是不是完全二叉树)
//判断是不是完全二叉树
bool BTComplete(BTNode* root)
{
	//先分析完全二叉树的特点
	//连续,层序遍历
	Queue Q;
	QueueInit(&Q);

	if (root != NULL)
	{
		QueuePush(&Q, root);
	}

	int size = 0;
	while (!QueueEmpty(&Q))
	{
		BTNode* front = QueueFront(&Q);
		//当节点里出现NULL了,那就做一个标记
		//记录这个时候已经出现过NULL了
		if (!front)
		{
			//如果front是NULL,就做标记
			size = 1;
		}
		//根据标记,可以知道,之前已经出现过NULL了
		if (front && size == 1)
		{
			//之前已经出现过NULL了,但是却出现了正常数字
			return false;
		} 
		QueuePop(&Q);

		if (front)
		{
			QueuePush(&Q, front->left);
			QueuePush(&Q, front->right);
		}
	}

	QueueDestroy(&Q);
	return true;
}
从牛客网上拷贝出来的,可以直接提交的完整代码
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param root TreeNode类 
 * @return bool布尔型
 */

typedef struct TreeNode* QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void QueueInit(Queue* pq)
{


	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{


	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QDataType x)
{

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail\n");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)
	{


		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}


	pq->size++;
}

void QueuePop(Queue* pq)
{



	// 1、一个节点
	// 2、多个节点
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		// 头删
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}

	pq->size--;
}

QDataType QueueFront(Queue* pq)
{



	return pq->phead->data;
}

QDataType QueueBack(Queue* pq)
{



	return pq->ptail->data;
}

int QueueSize(Queue* pq)
{


	return pq->size;
}

bool QueueEmpty(Queue* pq)
{

	/*return pq->phead == NULL
		&& pq->ptail == NULL;*/
	return pq->size == 0;
}



bool isCompleteTree(struct TreeNode* root )
{
    //先分析完全二叉树的特点
	//连续,层序遍历
	Queue Q;
	QueueInit(&Q);

	if (root != NULL)
	{
		QueuePush(&Q, root);
	}

	int size = 0;
	while (!QueueEmpty(&Q))
	{
		struct TreeNode* front = QueueFront(&Q);
		if (!front)
		{
			size = 1;
		}
		if (front && size == 1)
		{
			return false;
		} 
		QueuePop(&Q);

		if (front)
		{
			QueuePush(&Q, front->left);
			QueuePush(&Q, front->right);
		}
	}

	QueueDestroy(&Q);
	return true;
}

总结

以上就是今天要讲的内容,本文简单介绍了 牛客网_NC198.判断是不是完全二叉树 的解题思路,在力扣以及牛客网中还会有很多类似的题目,今后将会持续更新,敬请关注!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CtrlZ大牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值