1127 ZigZagging on a Tree(PAT)

   emmm....这道题的意思比较清楚,就是叫我们先中序后序建树,然后层序遍历,但是这个层序遍历每一层遍历次序都要相反

中需后续建树就不用说了,不会的拖出去打三十大板再回来...需要注意的就是可以用哈希表优化一下查找,即用unordered_map容器

预先存储中序遍历中每个数的位置,查找就不用循环了。

 然后就是如何层序遍历取反了,其实还是可以用层序遍历的公式,一层一层得处理(循环开始时用size储存该层的个数,然后循环size次),

只不过是用双端队列deque容器,这个容器支持两边出队和入队,然后用一个flg标记一下就好啦

代码:

#include<iostream>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<cmath>
#include<string.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define INT_MIN -2147483648
#define INT_MAX 2147483647
const int maxn = 35;
int read() {
    char p;
    while ((p = getchar()) < '0' || p > '9');
    int sum = p - 48;
    while ((p = getchar()) >= '0' && p <= '9')sum = sum * 10 + p - '0';
    return sum;
}
int tree[maxn][2];
int val[maxn];
int tot = 0;
unordered_map<int, int>M;
vector<int>v[2];
int n;
int build(int st1, int ed1, int st2, int ed2) {
    if (st1 > ed1)return -1;
    val[++tot] = v[0][ed1];
    int rt = tot;
    int pos = M[v[0][ed1]];//用之前哈希存的位置直接读取就行了
    tree[rt][0] = build(st1, pos - st2 + st1-1, st2, pos-1);
    tree[rt][1] = build(pos - st2 + st1, ed1 - 1, pos + 1, ed2);
    return rt;
}
void level_order(int rt) {
    deque<int>Q;//这个容器支持两边插入和删除
    Q.push_back(rt);
    bool flg = 0,h=0;
    int t;
    while (!Q.empty()) {
        int size = Q.size();
        for (int k = 0; k <size; k++) {//处理该层的节点,这里我size写成Q.size(),找了好久的错,呜呜呜...
            if (flg) {
                t = Q.front(); Q.pop_front();
                if (tree[t][0] != -1)Q.push_back(tree[t][0]);
                if (tree[t][1] != -1)Q.push_back(tree[t][1]);
            }
            else {
                t = Q.back(); Q.pop_back();
                if (tree[t][1] != -1)Q.push_front(tree[t][1]);//注意反向的时候要右孩子先入队,可以自己思考一下
                if (tree[t][0] != -1)Q.push_front(tree[t][0]);
            }
            if (h)printf(" ");
            printf("%d", val[t]);
            h = 1;
        }
        flg = !flg;//翻转
    }
}
int main() {
    //freopen("test.txt", "r", stdin);
    n = read();
    v[0].resize(n); v[1].resize(n);
    //cout << 1 << endl;
    for (int i = 0; i < n; i++) {
        v[1][i] = read();
        M[v[1][i]] = i;//把中序遍历中元素位置存储起来
    }
    for (int i = 0; i < n; i++) {
        v[0][i] = read();
    }
    //cout << 2 << endl;
    int root=build(0,n-1,0,n-1);
    level_order(root);
    return 0;
}
View Code

 

posted @ 2021-01-29 18:13  cono奇犽哒  阅读(37)  评论(0)    收藏  举报