PAT甲组1110 Complete Binary Tree思路解析和代码

A1110

题目链接

个人思路

  • 找根节点:输入数据,标记数据中的子节点,其中未被标记(不是其他节点的子节点),说明是根节点
  • 完全二叉树的判断依据:层序遍历该二叉树,
    1、若当前节点的左孩子为空,右孩子不为空,则非完全二叉树;
    2、若发现某个节点没有右孩子则进行标记,在这之后入队的节点如果不是叶子节点那么就不是完全二叉树。

出错点

  • 数据输入问题:数据范围是0~20,因此存在两位数,不能用单个字符接收数据,要用字符数组接收10 ~ 20之间的两位数数据
  • 判断条件问题:当节点的右孩子为空,说明之后的所有节点应为叶子节点(可能包含当前节点),但是不能把判断条件改为左孩子不空,右孩子空,此判断条件过于特殊,无法AC

个人思路错误代码

#include <bits/stdc++.h>
using namespace std;
int hashtable[25];//寻找根节点 
bool inq[25];
int N, root;
struct Node{
	int data;
	int left, right;
	Node(){}
	Node(int d, int l, int r)
	{
		data = d;
		left = l;
		right = r;
	}
}nodes[105];
int bfs(int cnt)
{
	bool isleaf = false;
	queue<Node> q;
	q.push(nodes[root]);
	inq[root] = true;
	while(!q.empty())
	{
		Node now = q.front();
		q.pop();
		cnt++;//出队时方才计数,不能在入队时计数 
		//判断 
		if(isleaf == true)
		{
			if(now.left != -1 || now.right != -1)
				return -1;
		}
		if(now.left == -1 && now.right != -1)//左孩子为空,右孩子不空 
			return -1;
		else if(now.left != -1 && now.right == -1)//左孩子不空,右孩子空 
		{
			isleaf = true;//后面入队的均为叶子节点 
		}
		if(cnt == N)
			return now.data;
		//入队
		if(now.left != -1 && inq[now.left] == false)
		{
			q.push(nodes[now.left]);
			inq[now.left] = true;
		}
		if(now.right != -1 && inq[now.right] == false)
		{
			q.push(nodes[now.right]);
			inq[now.right] = true;
		}
	}
}
int main(int argc, char *argv[]) {
	scanf("%d", &N);
	for(int i = 0; i < N; ++i)
	{
		char l, r;
		int ll, rr;
		getchar();
		scanf("%c %c", &l, &r);
		if(l == '-')
			ll = -1;
		else
			ll = l - '0';
		if(r == '-')
			rr = -1;
		else
			rr = r - '0';
		nodes[i] = Node(i, ll, rr);
		hashtable[ll] = hashtable[rr] = 1;
	}
	for(int i = 0; i < N; ++i)
	{
		if(hashtable[i] == 0)
		{
			root = i;
			break;
		}
	}
	int flag = bfs(0);
	if(flag == -1)//不是完全二叉树 
	{
		printf("NO %d", root);
	}
	else
	{
		printf("YES %d", flag);
	}
	return 0;
}

在这里插入图片描述

AC代码

//完全二叉树的判断依据是:层序遍历该二叉树,1、若当前节点的左孩子为空,右孩子不为空,则非完全二叉树;
//2、若发现某个节点没有右孩子则进行标记,在这之后入队的节点如果不是叶子节点那么就不是完全二叉树。
#include <bits/stdc++.h>
using namespace std;
int hashtable[25];//寻找根节点 
bool inq[25];
int N, root;
struct Node{
	int data;
	int left, right;
	Node(){}
	Node(int d, int l, int r)
	{
		data = d;
		left = l;
		right = r;
	}
}nodes[105];
int bfs(int cnt)
{
	bool isleaf = false;
	queue<Node> q;
	q.push(nodes[root]);
	inq[root] = true;
	while(!q.empty())
	{
		Node now = q.front();
		q.pop();
		cnt++;//出队时方才计数,不能在入队时计数 
		//判断 
		if(isleaf == true)
		{
			if(now.left != -1 || now.right != -1)
				return -1;
		}
		if(now.left == -1 && now.right != -1)//左孩子为空,右孩子不空 
			return -1;
			
		//if(now.left == -1 && now.right == -1)!!!此条件错误 
		if(now.right == -1)//左孩子不空,右孩子空 
		{
			isleaf = true;//后面入队的均为叶子节点 
		}
		if(cnt == N)
			return now.data;
		//入队
		if(now.left != -1)
		{
			q.push(nodes[now.left]);
			inq[now.left] = true;
		}
		if(now.right != -1)
		{
			q.push(nodes[now.right]);
			inq[now.right] = true;
		}
		/*if(q.empty())//与cnt == N均可作为判断条件,二选一 
			return now.data;*/
	}
}
int main(int argc, char *argv[]) {
	scanf("%d", &N);
	//getchar();
	for(int i = 0; i < N; ++i)
	{
		char l[3], r[3];//注意数据范围是0~20,因此不能用单个字符接收,否则无法接收12,13等两位数数据 
		int ll, rr;
		//getchar();
		scanf("%s %s", l, r);
		if(l[0] == '-')
			ll = -1;
		else
			sscanf(l, "%d", &ll);
		if(r[0] == '-')
			rr = -1;
		else
			sscanf(r, "%d", &rr);
		nodes[i] = Node(i, ll, rr);
		hashtable[ll] = hashtable[rr] = 1;
	}
	for(int i = 0; i < N; ++i)
	{
		if(hashtable[i] == 0)
		{
			root = i;
			break;
		}
	}
	int flag = bfs(0);
	if(flag == -1)//不是完全二叉树 
	{
		printf("NO %d", root);
	}
	else
	{
		printf("YES %d", flag);
	}
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值