题意
根据中后序建树,然后对于不同的查询判断正确性
代码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;
}
}
}
本文介绍了一种根据中序和后序遍历构建二叉树的方法,并实现了多种查询功能,包括查找根节点、兄弟节点、父节点、左右子节点、同一层级节点及检查树是否完全二叉树。
828

被折叠的 条评论
为什么被折叠?



