P1305 新二叉树题解

题目传送门

一、总结与感悟

1、二叉树遍历的代码模板

const int N = 1e6 + 10;

//树的结构体+存储数组
//此处:为二叉树的标准创建、遍历模板,可用于其它试题!
struct Node {
    int id;     // 当前结点ID
    int left;   // 左结点ID
    int right;  // 右结点ID
    char value; //当前结点的value值
} t[N];

//前序遍历
void pre_order(Node node) {
    //利用递归前序输出二叉树
    if (node.id) {
        cout << node.value << " ";
        pre_order(t[node.left]);
        pre_order(t[node.right]);
    }
}

//中序遍历
void in_order(Node node) {
    //利用递归前序输出二叉树
    if (node.id) {
        in_order(t[node.left]);
        cout << node.value << " ";
        in_order(t[node.right]);
    }
}


//后序遍历
void post_order(Node node) {
    //利用递归前序输出二叉树
    if (node.id) {
        post_order(t[node.left]);
        post_order(t[node.right]);
        cout << node.value << " ";
    }
}

//层序遍历
void level_order(Node node) {
    queue<Node> q;
    //放入第一个
    q.push(node);
    while (!q.empty()) {
        Node n1 = q.front();
        q.pop();
        cout << n1.value << " ";
        if (n1.left > 0) q.push(t[n1.left]);
        if (n1.right > 0) q.push(t[n1.right]);
    }
}

2、本题中没有告诉1号结点就是根,这一点有些坑人,需要用一个b数组,它是桶,记录了每个结点出现的次数,只出现一次的就是根,这样就可以很容易找到根。

二、C++代码

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 10;

//树的结构体+存储数组
//此处:为二叉树的标准创建、遍历模板,可用于其它试题!
struct Node {
    int id;     // 当前结点ID
    int left;   // 左结点ID
    int right;  // 右结点ID
    char value; //当前结点的value值(本题中未使用)
} t[N];

//前序遍历
void pre_order(Node node) {
    //利用递归前序输出二叉树
    if (node.id) {
        cout << node.value;
        pre_order(t[node.left]);
        pre_order(t[node.right]);
    }
}

int n;

/**
 测试用例:
 6
abc
bdi
cj*
d**
i**
j**

参考答案:abdicj
 */
int b[N];

int main() {
    cin >> n; //二叉树的结点数量
    //读入每个结点及它的左右儿子
    for (int i = 1; i <= n; i++) {
        string str;
        cin >> str;
        int j = str[0] - 'a' + 1;//结点编号
        b[j]++;//没有父亲的才是根
        //结点编号
        t[j].id = j;
        //记录字母值
        t[j].value=str[0];
        //记录左儿子
        if (str[1] != '*') t[j].left = str[1] - 'a' + 1, b[t[j].left]++;;
        //记录右儿子
        if (str[2] != '*') t[j].right = str[2] - 'a' + 1, b[t[j].right]++;;
    }
    //第一次提交,30分,似乎要求通过运算找到根,第一个输入的未必是根
    //第二次,记录谁是根,AC。
    int root;
    for (int i = 1; i <= 26; i++)
        if (b[i] == 1) {
            root = i;
            break;
        }
    //前序遍历
    pre_order(t[root]);
    return 0;
}
原文地址:https://www.cnblogs.com/littlehb/p/15101614.html