PTA 天梯賽練習 7-11 玩轉二叉樹
由樹的先序和中序遍歷序列建立一個二叉樹,做鏡面反轉後層次輸出
題目連接
7-11 玩轉二叉樹(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
解題思路
1.樹的建立,遍歷以及其他操作普遍用到遞歸的方法(樹的定義就是遞歸定義的,所以性質決定方法)
2.層次遍歷顯然用廣搜
3.前中序建立則從前向後【由前序序列從前向後確定樹的每個節點】(先左子樹後右子樹)
4.中後序建立則從後向前【由後序序列從後向前確定樹的每個節點】(先右子樹後左子樹)
注:由後序序列和中序序列建立方法見上一篇博客。
5.最重要的有兩點:一是左右子樹的長度,二是每次加入樹的結點數組下標
在中後序建立時直接通過下標計算長度即可,而前中序建立時添加一個變量來記錄
#include<bits/stdc++.h>
using namespace std;
int pre[40];
int ins[40];
typedef struct node{
int data;
struct node *l,*r;
}Node,*tree;
queue<tree>q;
int n;
void creatree(tree &t,int start,int last,int len){
int inx;
if(len<=0){
t=NULL;
return ;
}
else{
t=(tree)malloc(sizeof(Node));
t->data=pre[start];
for(int i=0;i<n;i++){
if(ins[i]==pre[start]){
inx=i;
break;
}
}
int lenf=inx-last;
creatree(t->l,start+1,last,lenf);
int lenr=len-1-lenf;
creatree(t->r,start+lenf+1,inx+1,lenr);
}
return;
}
void fanzhuan(tree &t){
if(t==NULL){
return;
}
if(t->l!=NULL&&t->r!=NULL){
tree temp;
temp=t->l;
t->l=t->r;
t->r=temp;
}
else if(t->l==NULL&&t->r!=NULL){
t->l=t->r;
t->r=NULL;
}
else if(t->l!=NULL&&t->r==NULL){
t->r=t->l;
t->l=NULL;
}
fanzhuan(t->l);
fanzhuan(t->r);
return;
}
void ceng(tree t){
if(t!=NULL){
q.push(t);
}
while(!q.empty()){
tree temp=q.front();
cout<<temp->data;
q.pop();
if(temp->l!=NULL){
q.push(temp->l);
}
if(temp->r!=NULL){
q.push(temp->r);
}
if(!q.empty()){
cout<<" ";
}
}
}
int main(){
tree t;
t=NULL;
cin>>n;
for(int i=0;i<n;i++){
cin>>ins[i];
}
for(int i=0;i<n;i++){
cin>>pre[i];
}
creatree(t,0,0,n);
fanzhuan(t);
ceng(t);
cout<<endl;
return 0;
}