题目:
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
分析:
知道二叉树的知知中序遍历和前序遍历,求后序遍历
1.镜面反转:这个其实就只要在递归的时候先递归右树,再递归左树就好;
2.层序遍历:
不同的层放在一个vector中,每层可以区分开,在递归过程中,当做一个完全满二叉树来看,初始化vector数组为-1(表示二叉树节点都为Null),将每个值放在对应节点上,输出时,特判一下-1(即为空)的状态即可。
3.复习:创建vector容器的三种方式
(1)不指定元素个数:
vector<int>v;
(2)指定容器的大小
vector<int>v(10);
(3)指定容器的大小,且每个元素具有指定的初始值。
vector<double>(10,8.6);
4.利用递归,从前序一个个元素开始,root=1; 在中序中找到a[root]==b[i]a[root]==b[i]a[root]==b[i],
然后将中序分为两部分,b[1.....i−1]和b[i+1.....n]b[1.....i-1] 和b[i+1.....n]b[1.....i−1]和b[i+1.....n],然后分别遍历这两
部分,直到这两部分元素为0(x>y) 或1个(x==y);
- 左子树 ,左子树范围必定在x到i-1之间,下一个根的位置在root+1
- 右子树,右子树范围必定在i+1到y之间,根的位置就是(i-x)是左子树
的大小,相当于root位置往后移左子树的个数再加一
前序遍历:根左右
中序遍历:左根右
后序遍历:左右根
AC代码:
#include <iostream>
#include<stdio.h>
#include <vector>
#define N 31
using namespace std;
int a[N],b[N];
vector<int> ve(100000,-1);
void build(int x,int y,int root,int step)/**x,y为左子树或右子树的区间,root为根节点,step为当前根节点的位置(满二叉树)*/
{if(x>y) return;ve[step]=a[root];/**记录当前根节点的位置*/int i;for(i=x;i<=y;++i){if(a[root]==b[i])break;}build(i+1,y,root+(i-x)+1,step*2+1);build(x,i-1,root+1,step*2+2);/**镜面这个其实就只要在递归的时候先递归右树,再递归左树就好*/
}
int main()
{int n;cin>>n;for(int i=1;i<=n;++i)cin>>b[i];for(int i=1;i<=n;++i)cin>>a[i];build(1,n,1,0);int cnt=0;for(int i=0;i<ve.size()&&cnt<=n;++i){if(ve[i]!=-1){if(i)cout<<" ";cout<<ve[i];++cnt;}}return 0;
}