Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.
Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:
- A is the root
- A and B are siblings
- A is the parent of B
- A is the left child of B
- A is the right child of B
- A and B are on the same level
- It is a full tree
Note:
- Two nodes are on the same level, means that they have the same depth.
- A full binary tree is a tree in which every node other than the leaves has two children.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than 103 and are separated by a space.
Then another positive integer M (≤30) is given, followed by M lines of statements. It is guaranteed that both A
and B
in the statements are in the tree.
Output Specification:
For each statement, print in a line Yes
if it is correct, or No
if not.
Sample Input:
9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree
Sample Output:
Yes
No
Yes
No
Yes
Yes
Yes
新手刷题,遇到树知识点的大杂烩,一点一点把各个独立考点拼起来,纪念一下AC(代码太长,每个功能点分的太细了)
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <unordered_map>
#include <algorithm>
using namespace std;
string arr[7] = {"root", "siblings", "parent", "left", "right", "level", "full"};
struct BiNode
{
int value, height;
BiNode *lchild, *rchild, *parent;
} *BiTree;
vector<int> postOrder, inOrder;
queue<BiNode *> level;
unordered_map<int, BiNode *> myMap;
// 根据后序和中序构建二叉树
BiNode *construct(int pl, int pr, int il, int ir)
{
if (pl > pr)
return NULL;
BiNode *pnode = (BiNode *)malloc(sizeof(BiNode));
pnode->value = postOrder[pr];
myMap[pnode->value] = pnode;
int pos = find(inOrder.begin(), inOrder.end(), pnode->value) - inOrder.begin();
pnode->lchild = construct(pl, pr - (ir - pos) - 1, il, pos - 1);
if (pnode->lchild != NULL)
pnode->lchild->parent = pnode;
pnode->rchild = construct(pr - (ir - pos), pr - 1, pos + 1, ir);
if (pnode->rchild != NULL)
pnode->rchild->parent = pnode;
return pnode;
}
// 判断一个数是否是full二叉树
bool isFull = true;
void judge(BiNode *node)
{
if (node != NULL)
if (node->lchild == NULL && node->rchild != NULL)
isFull = false;
else if (node->rchild == NULL && node->lchild != NULL)
isFull = false;
else
{
judge(node->lchild);
judge(node->rchild);
}
}
int main()
{
int n, k;
cin >> n;
postOrder.resize(n + 1);
inOrder.resize(n + 1);
for (int i = 0; i < n; i++)
cin >> postOrder[i];
for (int i = 0; i < n; i++)
cin >> inOrder[i];
BiTree = construct(0, n - 1, 0, n - 1);
judge(BiTree);
BiTree->height = 1;
level.push(BiTree);
// 使用队列得出树中每个节点的高度
while (!level.empty())
{
BiNode *node = level.front();
level.pop();
if (node->lchild != NULL)
{
node->lchild->height = node->height + 1;
level.push(node->lchild);
}
if (node->rchild != NULL)
{
node->rchild->height = node->height + 1;
level.push(node->rchild);
}
}
cin >> k;
// 一定要加getchar();不然输入后出错
getchar();
string input;
for (int i = 0; i < k; i++)
{
getline(cin, input);
int j = 0;
for (j = 0; j < 7; j++)
if (input.find(arr[j]) != string::npos)
break;
string temp;
//我看有的大佬用的是sscanf;我这里用的是istringstream;
istringstream str(input);
vector<string> stringArr;
while (str >> temp)
stringArr.push_back(temp);
if (j == 0)
if (stoi(stringArr[0]) == BiTree->value)
printf("Yes\n");
else
printf("No\n");
else if (j == 1)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[2])];
if (x->parent == y->parent)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 2)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[5])];
if (x == y->parent)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 3)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[6])];
if (x == y->lchild)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 4)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[6])];
if (x == y->rchild)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 5)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[2])];
if (x->height == y->height)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 6)
{
if (isFull)
printf("Yes\n");
else
printf("No\n");
}
else
printf("No\n");
}
return 0;
}
后面想到可以直接把求结点高度的操作可以直接揉到判断是否是full二叉树的操作里面,缩短了代码。(所以最后代码段主要分为:1、构建二叉树 2、判断是否是full二叉树,同时求出各结点高度 3、判断输入是何种类型,得出相应结果
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <unordered_map>
#include <algorithm>
using namespace std;
string arr[7] = {"root", "siblings", "parent", "left", "right", "level", "full"};
struct BiNode
{
int value, height;
BiNode *lchild, *rchild, *parent;
} *BiTree;
vector<int> postOrder, inOrder;
queue<BiNode *> level;
unordered_map<int, BiNode *> myMap;
// 根据后序和中序构建二叉树
BiNode *construct(int pl, int pr, int il, int ir)
{
if (pl > pr)
return NULL;
BiNode *pnode = (BiNode *)malloc(sizeof(BiNode));
pnode->value = postOrder[pr];
myMap[pnode->value] = pnode;
int pos = find(inOrder.begin(), inOrder.end(), pnode->value) - inOrder.begin();
pnode->lchild = construct(pl, pr - (ir - pos) - 1, il, pos - 1);
if (pnode->lchild != NULL)
pnode->lchild->parent = pnode;
pnode->rchild = construct(pr - (ir - pos), pr - 1, pos + 1, ir);
if (pnode->rchild != NULL)
pnode->rchild->parent = pnode;
return pnode;
}
// 判断一个数是否是full二叉树,顺便得出每个结点的高度
bool isFull = true;
void judge(BiNode *node)
{
if (node != NULL)
{
if (node->lchild == NULL && node->rchild != NULL)
isFull = false;
else if (node->rchild == NULL && node->lchild != NULL)
isFull = false;
if (node->lchild != NULL)
node->lchild->height = node->height + 1;
if (node->rchild != NULL)
node->rchild->height = node->height + 1;
judge(node->lchild);
judge(node->rchild);
}
}
int main()
{
int n, k;
cin >> n;
postOrder.resize(n + 1);
inOrder.resize(n + 1);
for (int i = 0; i < n; i++)
cin >> postOrder[i];
for (int i = 0; i < n; i++)
cin >> inOrder[i];
BiTree = construct(0, n - 1, 0, n - 1);
BiTree->height = 1;
judge(BiTree);
cin >> k;
getchar(); // 一定要加getchar();不然输入后出错
string input;
for (int i = 0; i < k; i++)
{
getline(cin, input);
int j = 0;
for (j = 0; j < 7; j++)
if (input.find(arr[j]) != string::npos)
break;
string temp;
// 我看有的大佬用的是sscanf;我这里用的是istringstream;
istringstream str(input);
vector<string> stringArr;
while (str >> temp)
stringArr.push_back(temp);
if (j == 0)
if (stoi(stringArr[0]) == BiTree->value)
printf("Yes\n");
else
printf("No\n");
else if (j == 1)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[2])];
if (x->parent == y->parent)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 2)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[5])];
if (x == y->parent)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 3)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[6])];
if (x == y->lchild)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 4)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[6])];
if (x == y->rchild)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 5)
{
BiNode *x = myMap[stoi(stringArr[0])];
BiNode *y = myMap[stoi(stringArr[2])];
if (x->height == y->height)
printf("Yes\n");
else
printf("No\n");
}
else if (j == 6)
{
if (isFull)
printf("Yes\n");
else
printf("No\n");
}
else
printf("No\n");
}
return 0;
}