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; }