PAT 2019春考 7-4 Structure of a Binary Tree

#include <bits/stdc++.h>

using namespace std;

const string pattern[7] = {
    "[0-9]+ is the root",
    "[0-9]+ and [0-9]+ are siblings",
    "[0-9]+ is the parent of [0-9]+",
    "[0-9]+ is the left child of [0-9]+",
    "[0-9]+ is the right child of [0-9]+",
    "[0-9]+ and [0-9]+ are on the same level",
    "It is a full tree"};

int requestMatch(string in)
{
    for (size_t i = 0; i < 7; i++)
    {
        regex r(pattern[i]);
        smatch results;

        if (regex_match(in, results, r))
            return i;
    }

    return -1;
}

class node
{
  public:
    int m_level = -1;
    int m_parent = -1;
    int m_lchild = -1;
    int m_rchild = -1;
};

class tree
{
  public:
    int m_root = -1;
    map<size_t, node> m_allNode;
    size_t m_nodes = 0;
    vector<int> m_postorder;
    vector<int> m_inorder;

    tree(size_t nodes) { m_nodes = nodes; }

    void treeParse() { m_root = treeParsing(0, 0, m_nodes - 1, -1); }

    bool isRoot(int n) { return (n == m_root); }

    bool isSiblings(int a, int b) { return (m_allNode[a].m_parent == m_allNode[b].m_parent); }

    bool isParent(int p, int c) { return (m_allNode[c].m_parent == p); }

    bool isLChild(int lc, int p) { return (m_allNode[p].m_lchild == lc); }

    bool isRChild(int rc, int p) { return (m_allNode[p].m_rchild == rc); }

    bool isSameLevel(int a, int b) { return (m_allNode[a].m_level == m_allNode[b].m_level); }

    bool isFullTree()
    {
        queue<int> s_nodes;
        s_nodes.push(m_root);

        while (!s_nodes.empty())
        {
            int temp = s_nodes.front();
            s_nodes.pop();

            if ((m_allNode[temp].m_lchild == -1) != (m_allNode[temp].m_rchild == -1))
            {
                return false;
            }
            else if (m_allNode[temp].m_lchild != -1)
            {
                s_nodes.push(m_allNode[temp].m_lchild);
                s_nodes.push(m_allNode[temp].m_rchild);
            }
        }

        return true;
    }

  private:
    int treeParsing(size_t level, int start, int end, int parent)
    {
        for (int i = m_nodes - 1; i >= 0; i--)
        {
            for (int j = start; j <= end; j++)
            {
                if (m_inorder[j] == m_postorder[i])
                {
                    m_allNode[m_postorder[i]].m_level = level;
                    m_allNode[m_postorder[i]].m_parent = parent;
                    m_allNode[m_postorder[i]].m_lchild = treeParsing(level + 1, start, j - 1, m_postorder[i]);
                    m_allNode[m_postorder[i]].m_rchild = treeParsing(level + 1, j + 1, end, m_postorder[i]);

                    return m_postorder[i];
                }
            }
        }

        return -1;
    }
};

int main()
{
    size_t n, temp, req;

    cin >> n;
    tree tr(n);

    for (size_t i = 0; i < tr.m_nodes; i++)
    {
        cin >> temp;
        tr.m_postorder.push_back(temp);
    }
    for (size_t i = 0; i < tr.m_nodes; i++)
    {
        cin >> temp;
        tr.m_inorder.push_back(temp);
    }

    tr.treeParse();

    cin >> req;
    getchar();

    for (size_t i = 0; i < req; i++)
    {
        int a, b, ret;
        char in[100];
        cin.getline(in, sizeof(in), '\n');
        switch (requestMatch(in))
        {
        case 0:
            sscanf(in, "%d is the root", &a);
            ret = tr.isRoot(a);
            break;
        case 1:
            sscanf(in, "%d and %d are siblings", &a, &b);
            ret = tr.isSiblings(a, b);
            break;
        case 2:
            sscanf(in, "%d is the parent of %d", &a, &b);
            ret = tr.isParent(a, b);
            break;
        case 3:
            sscanf(in, "%d is the left child of %d", &a, &b);
            ret = tr.isLChild(a, b);
            break;
        case 4:
            sscanf(in, "%d is the right child of %d", &a, &b);
            ret = tr.isRChild(a, b);
            break;
        case 5:
            sscanf(in, "%d and %d are on the same level", &a, &b);
            ret = tr.isSameLevel(a, b);
            break;
        case 6:
            ret = tr.isFullTree();
            break;
        default:
            break;
        }

        cout << ((ret) ? "Yes\n" : "No\n");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值