【PAT甲级】 1159 Structure of a Binary Tree

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.
  • 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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值