1.题目
L2-011 玩转二叉树
分数 25
全屏浏览
切换布局
作者 陈越
单位 浙江大学
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
2.分析
由于本题的N的范围在30以内,因此我们利用静态的二叉树也可以完成(无指针),题目中说要把二叉树做个镜面反转。
我会给出静态和动态的两种解法。(其实二者大体思路差不多)
二叉树进行(左子树,根节点,右子树)地递归就是其前序遍历。
二叉树进行(右子树,根节点,左子树)地递归就是其镜像的前序遍历。
题目给出二叉树的中序和前序遍历。
先给出还原二叉树的代码:
void addTree(int a,int b,int uns){
if(a>b) return;
t[uns].w=front[n++];
t[uns].l=uns*2; //定义其左子树的下标为2*uns
t[uns].r=uns*2+1; //定义其右子树的下标为2*uns+1
int i;
for( i=a;i<=b;i++){
if(t[uns].w==center[i])
break;
} //因为是前序遍历,先左后右
addTree(a,i-1,2*uns); //递归左子树
addTree(i+1,b,2*uns+1); //递归右子树
}
但这样只能构建出二叉树,并没有对其进行镜像反转(非叶结点的左右孩子对换);
因此我们可以在递归时改变其左右子树。
addTree(a,i-1,2*uns+1);
addTree(i+1,b,2*uns);
经过对比,我们相当于变相交换了 非叶结点的左右孩子。
动态也一样
root->l = addtree(a,i-1);
root->r = addtlree(i+1,b);
变成
root->r = addtree(a,i-1);
root->l = addtree(i+1,b);
这样就好办了,我们只需要利用队列对其进行层序遍历就行了。
3.代码
静态.........................
#include<iostream>
#include<queue>
using namespace std;
const int MAX=10010;
//树的结构体
struct tree{
int l,r,w;
}t[MAX];
int N,front[MAX],center[MAX],n=1; //n用于记录前序下标
void addTree(int a,int b,int uns){
if(a>b) return;
t[uns].w=front[n++];
t[uns].l=uns*2; //左子树
t[uns].r=uns*2+1; //右子树
int i;
for( i=a;i<=b;i++){
if(t[uns].w==center[i])
break;
}
addTree(a,i-1,2*uns+1);
addTree(i+1,b,2*uns);
}
//层序遍历
void bfs(){
queue<int> q;
q.push(1);
int f=0;
while(!q.empty()){
int x=q.front();
if(t[x].w){
if(f) cout<<" "<<t[x].w;
else f=1,cout<<t[x].w;
}
q.pop();
if(t[x].l) q.push(t[x].l);
if(t[x].r) q.push(t[x].r);
}
}
int main(){
cin>>N;
for(int i=1;i<=N;i++){cin>>center[i];}
for(int i=1;i<=N;i++){cin>>front[i];}
addTree(1,N,1);
bfs();
return 0;
}
动态............................
#include<iostream>
#include<queue>
using namespace std;
//二叉树的结构体
struct Tree{
int value;
Tree* l, * r;
};
int N,center[40],front[40],n=1; //n用来记录前序下标
//建树函数
Tree* addtree(int a,int b){
if (a > b) return NULL;
Tree* root = new Tree;
root->value = front[n++];
root->l = NULL;
root->r = NULL;
int i;
for (i = a; i <= b; i++) {
if (root->value == center[i]) break;
}
root->r = addtree(a,i-1); //变相交换左右子树
root->l = addtree(i+1,b);
return root;
}
//层序遍历
void bfs(Tree* root) {
if (root == nullptr) {return;}
queue<Tree*> q;
q.push(root);
int f = 0;
while (!q.empty()) {
Tree* t = q.front();
q.pop();
if (f) cout << " " << t->value;
else f = 1, cout << t->value;
if (t->l) {q.push(t->l);}
if (t->r) {q.push(t->r);}
}
}
int main()
{
cin >> N ;
for (int i = 1; i <= N; i++) { cin >> center[i]; }
for (int i = 1; i <= N; i++) { cin >> front[i]; }
Tree* r = addtree(1,N);
bfs(r);
return 0;
}