PAT甲级 1159 Structure of a Binary Tree (30 分)

本文介绍了一种根据中序和后序遍历构建二叉树的方法,并实现了多种查询功能,包括查找根节点、兄弟节点、父节点、左右子节点、同一层级节点及检查树是否完全二叉树。

题意

根据中后序建树,然后对于不同的查询判断正确性

代码1

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;

int post[35];
int in[35];
struct tree{
	int data;
	tree *left, *right, *father;
	tree(int a)
	{
		data = a;
		left = right = father = NULL;
	}
};

tree* build(int inl, int inr, int postl, int postr)//中后序建树 
{
	if (inl > inr || postl > postr) return NULL;
	tree *root = new tree(post[postr]);
	int i;
	for (i = inl; i <= inr; i++)
		if (in[i] == post[postr])
			break;
	root->left = build(inl, i-1, postl, postl + i-1-inl);
	root->right = build(i+1, inr, postl + i-1-inl+1, postr-1);
	if (root->left) root->left->father = root;
	if (root->right) root->right->father = root; 
	return root;
}

int get(string& s, int n)//得到一句话中的第n个单词,并转换成数字 
{
	int space[20]; space[0] = -1;
	int cnt = 0, i;
	for (i = 0; i < s.size(); i++)
	{
		if (s[i] == ' ')
			space[++cnt] = i;
	}
	space[++cnt] = i;
	return stoi(s.substr(space[n-1]+1, space[n]-space[n-1]-1));
}

tree *fin(tree* root, int data)//在一棵树中找到对应数值的指针 
{
	if (root)
	{
		if (root->data == data)
			return root;
		tree *p = fin(root->left, data);
		tree *q = fin(root->right, data);
		if (p) return p;
		else return q;
	}
	return NULL;
}

int count(tree *root, tree *p, int depth)//查询一个节点的深度 
{
	if (root)
	{
		depth++;
		if (root == p)
			return depth;
		int left = count(root->left, p, depth);
		int right = count(root->right, p, depth);
		if (left) return left;
		else return right;
	}
	return 0;
}

bool check(tree *root)//查询树是否full 
{
	if (root)
		return (root->left && root->right || !root->left && !root->right) && check(root->left) && check(root->right);
	return true;
}

int main(void)
{
	int i, j, temp;
	int n, q;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		scanf("%d", post+i);
	}
	for (i = 1; i <= n; i++)
	{
		scanf("%d", in+i);
	}
	tree *root = build(1, n, 1, n);
	scanf("%d", &q); getchar();
	while (q--)
	{
		string s;
		getline(cin, s);
		if (s.find("root") != string::npos)
		{
			int n = get(s, 1);
			if (root->data == n)
				printf("Yes");
			else
				printf("No");
		}
		else if (s.find("siblings") != string::npos)
		{
			int n = get(s, 1), m = get(s, 3);
			tree *p = fin(root, n), *q = fin(root, m);
			if (p->father == q->father)
				printf("Yes");
			else
				printf("No");
		}
		else if  (s.find("parent") != string::npos)
		{
			int n = get(s, 1), m = get(s, 6);
			tree *p = fin(root, n), *q = fin(root, m);
			if (q->father == p)
				printf("Yes");
			else
				printf("No");
		}
		else if  (s.find("left") != string::npos)
		{
			int n = get(s, 1), m = get(s, 7);
			tree *p = fin(root, n), *q = fin(root, m);
			if (q->left == p)
				printf("Yes");
			else
				printf("No");
		}
		else if  (s.find("right") != string::npos)
		{
			int n = get(s, 1), m = get(s, 7);
			tree *p = fin(root, n), *q = fin(root, m);
			if (q->right == p)
				printf("Yes");
			else
				printf("No");
		}
		else if  (s.find("level") != string::npos)
		{
			int n = get(s, 1), m = get(s, 3);
			tree *p = fin(root, n), *q = fin(root, m);
			int l1 = count(root, p, 0), l2 = count(root, q, 0);
			if (l1 == l2)
				printf("Yes");
			else
				printf("No");
		}
		else if (s.find("full") != string::npos)
		{
			if (check(root))
				printf("Yes");
			else
				printf("No");
		}
		printf("\n");
	}
}

代码2

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;

int post[35];
int in[35];
struct tree{
	int data;
	tree *left, *right, *father;
	int depth;
	tree(int a, int b)
	{
		data = a; depth = b;
		left = right = father = NULL;
	}
};
map<int, tree*> mp; 
bool full = true;

tree* build(int inl, int inr, int postl, int postr, int depth)
{
	tree *root = new tree(post[postr], depth);
	mp[post[postr]] = root;
	int i;
	for (i = inl; i <= inr; i++)
		if (in[i] == post[postr])
			break;
	if (i != inl)
	{
		root->left = build(inl, i-1, postl, postl+i-1-inl, depth+1);
		root->left->father = root;
	}
	if (i != inr)
	{
		root->right = build(i+1, inr, postl+i-1-inl+1, postr-1, depth+1);
		root->right->father = root;
	}
	if (root->left && !root->right || root->right && !root->left) full = false;
	return root;
}

int main(void)
{
	int i, j, temp;
	int n, q; cin >> n;
	for (i = 1; i <= n; i++) cin >> post[i];
	for (i = 1; i <= n; i++) cin >> in[i];
	tree *root = build(1, n, 1, n, 1);
	cin >> q; getchar();
	while(q--)
	{
		string s;
		getline(cin, s);
		int a, b;
		if (s.find("root") != string::npos)
		{
			sscanf(s.c_str(), "%d is the root", &a);
			if (root->data == a) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("siblings") != string::npos)
		{
			sscanf(s.c_str(), "%d and %d are siblings", &a, &b);
			if (mp[a]->father == mp[b]->father) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("parent") != string::npos)
		{
			sscanf(s.c_str(), "%d is the parent of %d", &a, &b);
			if (mp[b]->father == mp[a]) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("left") != string::npos)
		{
			sscanf(s.c_str(), "%d is the left child of %d", &a, &b);
			if (mp[b]->left == mp[a]) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("right") != string::npos)
		{
			sscanf(s.c_str(), "%d is the right child of %d", &a, &b);
			if (mp[b]->right == mp[a]) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("level") != string::npos)
		{
			sscanf(s.c_str(), "%d and %d are on the same level", &a, &b);
			if (mp[b]->depth == mp[a]->depth) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else if (s.find("full") != string::npos)
		{
			if (full) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
	} 
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值