天梯赛习题集 L2-011. 玩转二叉树
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
没啥好说的……就是被坑了一点,这上面是它的里面保存的值而不是它的目录值,所以目录值得自己定义,不然就会因为过大的整数导致爆内存。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#define ll long long
#define mem(tar,n) memset(tar,n,sizeof(tar))
#define FF(a,b,i) for(int i=a;i<b;i++)
using namespace std;
struct node {
int num;
int lc;
int rc;
node()
{
this->lc = 0;
this->rc = 0;
}
};
vector<int>in;
vector<node>sto;
vector<int>pre;
int n;
int cnt = 1;
int find(int tar,int in_l,int in_r)
{
FF(in_l,in_r+1, i)
{
if (in[i] == tar)
return i;
}
}
int cons(int in_l, int in_r, int pre_l, int pre_r)
{
if (pre_l == pre_r)
{
sto[cnt].num = pre[pre_l];
return cnt++;
}
int tar = pre[pre_l];
int tar_in = find(tar,in_l,in_r);
int cur = cnt++;
sto[cur].num = tar;
if(tar_in!=in_l)
sto[cur].lc = cons(in_l, tar_in - 1, pre_l + 1, pre_l + 1 + tar_in - in_l - 1);
if(tar_in!=in_r)
sto[cur].rc = cons(tar_in + 1, in_r, pre_l + 1 + tar_in - in_l, pre_r);
return cur;
}
void reverse(int tar)
{
swap(sto[tar].lc, sto[tar].rc);
if (sto[tar].lc != 0)reverse(sto[tar].lc);
if (sto[tar].rc != 0)reverse(sto[tar].rc);
}
int main()
{
cin >> n;
in.resize(n);
pre.resize(n);
sto.resize(n + 1);
FF(0, n, i)cin >> in[i];
FF(0, n, i)cin >> pre[i];
int head=cons(0, n - 1, 0, n - 1);
reverse(head);
queue<node>Q;
vector<int>ans;
Q.push(sto[1]);
while (Q.size())
{
ans.push_back(Q.front().num);
if (Q.front().lc != 0)Q.push(sto[Q.front().lc]);
if (Q.front().rc != 0)Q.push(sto[Q.front().rc]);
Q.pop();
}
FF(0, ans.size(), i)
{
if (i)cout << " " << ans[i];
else cout << ans[i];
}}