zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    最长k可重区间集问题【网络流24题】
    分配问题 【网络流24题】
    航空路线问题 【网络流24题】
    最长不下降子序列问题 【网络流24题】
    数组去重
    项目选题报告(团队)
    关于DLL的创建与使用简单描述(C++、C#)
    原型设计(结对第一次)
    团队展示(团队)
    第二次作业——个人项目实战
  • 原文地址:https://www.cnblogs.com/littlehb/p/15101614.html
Copyright © 2011-2022 走看看