pat 团体天梯赛 L2-011. 玩转二叉树

L2-011. 玩转二叉树

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2

思路:先依据前序和中序遍历重建二叉树,递归的对换左右孩子,最后中序遍历输出结果即可。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring> 
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define INF 0x3f3f3f3f
#define EPS 1e-5
#define pi cos(-1)
const int N_MAX = 1000000 + 10;

struct Node {
    int r, l, key;
}node[N_MAX];

vector<int> in,pre,post;

int n,pos=0;
void dfs(const int& l,const int &r,int n) {//找到后序遍历中区间[l,r]的根结点和左右子树
    if (l > r) {
        node[n].key = INF;
        return;
    }
    int root = post[pos++];
    node[n].l = 2 * n;
    node[n].r = 2 * n+1;
    node[n].key = root;
    int m = find(in.begin(), in.end(), root) - in.begin();
    dfs(l, m - 1, 2 * n);
    dfs(m + 1, r, 2 * n + 1);
}

void exchange(Node *node,int n) {//将所有非叶结点的左右孩子对换
    if (node[n].key == INF)return;
    if(node[n].l != 0)exchange(node, 2 * n);
    if(node[n].r != 0)exchange(node, 2 * n + 1);
    if (node[n].l != 0 && node[n].r != 0) {
        swap(node[n].l, node[n].r);//交换左右孩子
    }
}

void bfs() {
    queue<int>que;
    que.push(1);
    while (!que.empty()) {
        int p = que.front(); que.pop();
        if(node[p].key!=INF)pre.push_back(node[p].key);
        if (node[p].l != 0)que.push(node[p].l);
        if (node[p].r != 0)que.push(node[p].r);
    }
}

int main(){
    while (cin>>n) {
        pos = 0;
        in.resize(n);
        post.resize(n);
        for (int i = 0; i < n;i++) {
            cin >> in[i];
        }
        for (int i = 0; i < n;i++) {
            cin >> post[i];
        }
        dfs(0, n - 1, 1);
        exchange(node, 1);
        bfs();
        for (int i = 0; i < n;i++) {
            cout << pre[i];
            if (i + 1 == n)cout << endl;
            else cout << " ";
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ZefengYao/p/8127930.html