题目链接:https://www.patest.cn/contests/gplt/L2-011
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
解题思路:(比赛的时候,因为上次可以用数组解决,条件反射一直考虑数组,浪费了很多时间QAQ,最后还是用的链表。。。真的是服了- -)
其实根据前中遍历 找出树本身的序列并不难 我们先在前序遍历那里找出第一个元素 ,然后在 中序遍历里面找出这个元素,因为前序遍历先遍历根节点,所以在这个元素左边
就是左子树上的元素,右边就是右子树的元素。
按照样例来讲:在第二个序列找出第一个数就是4,然后在第一个序列找出4 这样根据中序遍历先左子树,然后根,最后右子树的规律 4为根(123)为左子树
(5,6,7)为右子树 ,接着 扫先序序列到1,1为根 ,1左边没有元素,故1没有左子树,右子树为(23),接着先序序列到3,3为根,(2)为左子树,接着到6,6为根。
左边的5为左子树,7为右子树,下面有丑图 0 0(好久没画图_(:з」∠)_)
反转的话- -很简单。翻转左子树,翻转右子树,数据结构的基本内容(忘了,自觉百度面壁去吧)
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
const int INF = 0x7fffffff;
int pre[maxn];
int mid[maxn];
int ans[maxn+20];
int n;
typedef struct node
{
struct node *l ;
struct node *r;
int data;
}*treenode,node;
node tmp;
void search_(int l,int r,treenode *root)
{
if(l>r)
return ;
int f= 0;
int rt;
// cout << 1<<endl;
for(int j = 0 ; j < n ; j ++)
{
for(int i = l ; i <= r ; i ++)
if(mid[i] == pre[j])
{
rt = i;
f=1;
break;
}
if(f)
break;
}
*root = (treenode)malloc(sizeof(node));
//cout << 1<<endl;
(*root)->l = NULL;
(*root)->r = NULL;
(*root)->data = mid[rt];
search_(l,rt-1,&((*root)->l));
search_(rt+1,r,&((*root)->r));
}
void re(treenode tp)
{
treenode t;
if(tp)
{
t = tp->r;
tp->r = tp->l;
tp->l = t;
re(tp->l);
re(tp->r);
}
}
int cnt = 0;
void transfver(node *tp)
{
queue<node *>que;
que.push(tp);
while(!que.empty())
{
tp = que.front();
que.pop();
if(tp->l)
{
que.push(tp->l);
}
if(tp->r)
{
que.push(tp->r);
}
ans[cnt++] = tp->data;
}
}
int main()
{
cin >> n;
for(int i = 0 ; i< n ; i++)
scanf("%d",&mid[i]);
for(int i = 0 ; i < n; i ++)
scanf("%d",&pre[i]);
node *tmp;
tmp =(treenode)malloc(sizeof(node));
search_(0,n-1,&tmp);
// cout << tmp ->data<<endl;
re(tmp);
transfver(tmp);
for(int i = 0 ; i < cnt - 1; i ++)
printf("%d ",ans[i]);
printf("%d\n",ans[cnt-1]);
return 0;
}