1110 Complete Binary Tree (25分)

题目链接:1110 Complete Binary Tree

题意

N个结点,结点值从0 - N-1。给出N个结点的左右子树下标。判断是否为完全二叉树,是则输出YES 和最后一个结点值,不是则输出根节点值。

分析

  1. 可用结构体存储结点值,和左右子树,只有根节点是没有指向的。所以判断没有出现的数字即为根节点。然后是bfs搜索,队列为结点的值,将空节点作为-1加入队列。当出现空节点后,完全二叉树是后面全部为空结点,否则不是。因此当出队的结点值为-1时,判断后面是否全部为-1的结点。
  2. dfs搜索,找到根节点后,从跟结点开始递归左右子树,完全二叉树排列在数组中是按照根节点一层一层顺序排列,可设index为每个结点对应数组中的下标,从1开始,若为完全二叉树,最后一个结点对应的index == n,否则index > n.

代码1—bfs

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
typedef struct Tree{
	int data;
	int left;
	int right;
}BiTree;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
BiTree tree[30];
int bfs(int root);
int n;
using namespace std;
int main(int argc, char** argv) {
	scanf("%d", &n);
	char s1[10], s2[10];
	getchar();
	int book[20] = {0};
	for (int i = 0; i < n; i++) {
		scanf("%s%s", s1, s2);
		int a = -1, b = -1;
		if (s1[0] != '-') {
			sscanf(s1, "%d", &a);
			book[a] = 1;
		}
		if (s2[0] != '-') {
			sscanf(s2, "%d", &b);
			book[b] = 1;
		}
		tree[i].data = i;
		tree[i].left = a;
		tree[i].right = b;
	}
	int root;
	for (int i = 0; i < n; i++) 
		if (book[i] == 0) {
			root = i;
			break;
		}
	int res = bfs(root);
	if (res != -1)
		printf("YES %d\n", res);
	else
		printf("NO %d\n", root);
	return 0;
}
int bfs(int root) {
	queue<int> que;
	que.push(root);
	int rear = root;
	while (!que.empty()) {
		int t = que.front();
		rear = t == -1 ? rear : t;
		que.pop();
		// 遇到空节点且后面还有不为空的结点则不为完全二叉树
		if (t == -1) {
			while(!que.empty() && que.front() == -1)
				que.pop();
			if (!que.empty())
				return -1; 
			else
				return rear;
		}
		if (tree[t].left != -1) 
			que.push(tree[t].left);
		else
			que.push(-1);
		if (tree[t].right != -1)
			que.push(tree[t].right);
		else
			que.push(-1);
	}
	return rear;
}


代码2—dfs

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
typedef struct Tree{
	int data;
	int left;
	int right;
}BiTree;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
BiTree tree[30];
int bfs(int root);
int n, maxNode = -1, ans = 0;
using namespace std;

void dfs(int root, int index) {
	if ( maxNode < index) {
		maxNode = index;
		ans = root;
	}
	if (tree[root].left != -1)
		dfs(tree[root].left, 2 * index);
	if (tree[root].right != -1)
		dfs(tree[root].right, 2 * index + 1);
}
int main(int argc, char** argv) {
	scanf("%d", &n);
	char s1[10], s2[10];
	getchar();
	int book[20] = {0};
	for (int i = 0; i < n; i++) {
		scanf("%s%s", s1, s2);
		int a = -1, b = -1;
		if (s1[0] != '-') {
			sscanf(s1, "%d", &a);
			book[a] = 1;
		}
		if (s2[0] != '-') {
			sscanf(s2, "%d", &b);
			book[b] = 1;
		}
		tree[i].data = i;
		tree[i].left = a;
		tree[i].right = b;
	}
	int root;
	for (int i = 0; i < n; i++) 
		if (book[i] == 0) {
			root = i;
			break;
		}
//	int res = bfs(root);
	dfs(root, 1);
	if (maxNode == n)
		printf("YES %d\n", ans);
	else
		printf("NO %d\n", root);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值