PAT甲级-1130 Infix Expression

题目

题目大意

给出一棵二叉树,树的元素是运算符号或字母、数字、字符串,要求按中序遍历输出算式,算式优先级用括号来表示。

思路

肯定要构建树,因为有特殊字符,所以用结构体数组来存储,每个节点都包含id,name(该节点实际表示的字符),左孩子和右孩子。然后再找到根节点方便接下来的遍历。

接着观察树的结构图和输出样例,发现每一个子树都被左右括号所包裹,除了叶子节点。因此在中序遍历时,可以用字符串res来记录最终结果,遍历左子树或右子树前,res插入一个'(',遍历完左子树或右子树后,res插入一个')'。

需要注意,叶子节点前后是没有括号的,因此可以加空格来区分哪个是叶子节点的括号,等遍历结束后,删除空格附近的括号即可。

代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

struct node{
    int id;
    string name;
    int lchild, rchild;
};

int n;
vector<node> v;
string res = "";

void traverseTree(int root){
    if (v[root].lchild == 0 && v[root].rchild == 0){
        res += " ";
        res += v[root].name;
        res += " ";  // 用空格作记号,标明应该删除的括号
        return;
    }else{
        if (v[root].lchild){
            res += "(";
            traverseTree(v[root].lchild);
            res += ")";
        }
        res += v[root].name;
        if (v[root].rchild){
            res += "(";
            traverseTree(v[root].rchild);
            res += ")";
        }
    }
}  // 中序遍历,并记录res

int main(){
    cin >> n;
    v.resize(n + 1);
    for (int i = 1; i <= n; i++){
        cin >> v[i].name;
        v[i].id = i;
        int lchild, rchild;
        cin >> lchild >> rchild;
        v[i].lchild = v[i].rchild = 0;
        if (lchild != -1){
            v[i].lchild = lchild;
        }
        if (rchild != -1){
            v[i].rchild = rchild;
        }
    }  // 构建树

    int root;
    vector<bool> b(n + 1);  // 节点有没有被当作子节点
    for (int i = 1; i <= n; i++){
        if (v[i].lchild){
            b[v[i].lchild] = true;
        }
        if (v[i].rchild){
            b[v[i].rchild] = true;
        }
    }
    for (int i = 1; i <= n; i++){
        if (!b[i]){
            root = i;
            break;
        }
    }  // 查找根节点

    traverseTree(root);
    for (int i = 0; i < (int)res.size() - 1; i++){
        if (res[i] == '(' && res[i + 1] == ' '){
            res.erase(i, 2);
            i--;
        }
        if (res[i] == ' ' && res[i + 1] == ')'){
            res.erase(i, 2);
            i--;
        }
    }  // 根据空格记号,删除多余的括号

    for (int i = 0; i < (int)res.size(); i++){
        if (res[i] == ' '){
            res.erase(i, 1);
            i--;
        }
    }  // 测试点2格式错误,将多余的空格去掉
    cout << res << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_74092648/article/details/143029061