給定一棵二叉樹的后序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這里假設鍵值都是互不相等的正整數。
輸入格式:
輸入第一行給出一個正整數N(<=30),是二叉樹中結點的個數。第二行給出其后序遍歷序列。第三行給出其中序遍歷序列。數字間以空格分隔。
輸出格式:
在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多余空格。
輸入樣例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
輸出樣例:
4 1 6 3 5 7 2
分析
對于后序遍歷序列 : 最后一個值是根,前面一部分是左兒子 , 中間一部分是右兒子。
比如樣例 : 4 是根 , 231 是左兒子 , 576 是右兒子。
如何找到哪一段是左兒子,哪一段是右兒子 ?
看中序遍歷序列 : 在中序遍歷序列中找到根 4 。 它左邊有3個數,全是它的左兒子。右邊同理。
這樣就找到左兒子是有三個數 , 右兒子是有 3 個數的,這樣看回后序遍歷序列。就知道前三個數是左兒子,緊接著的3個數是右兒子。
就這樣慢慢還原一棵樹。然后bfs層序輸出。
代碼如下
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#define CLR(x) memset(x,0,sizeof(x))
#define LL long long
using namespace std;
int mid[50],hou[50];
struct node{
int l , r;
}a[50];
int build(int la,int ra,int lb,int rb){
if(la > ra) return 0;
int rt = hou[rb];
int p1 = la , p2 ;
while(mid[p1] != rt) p1++;
p2 = p1 - la;
a[rt].l = build(la,p1-1,lb,lb+p2-1);
a[rt].r = build(p1+1,ra,lb+p2,rb-1);
return rt;
}
void bfs(int x)
{
queue<int> q;
vector<int> g;
q.push(x);
while(!q.empty()){
int w = q.front();
q.pop();
if(w == 0) break;
g.push_back(w);
if(a[w].l != 0){
q.push(a[w].l);
}
if(a[w].r != 0){
q.push(a[w].r);
}
}
for(int i = 0 ; i < g.size() ; i++){
printf("%d%c",g[i],i==g.size()-1 ? '\n' : ' ');
}
return;
}
int main()
{
int n;
cin >> n;
for(int i = 0 ; i < n ; i++) cin >> hou[i];
for(int i = 0 ; i < n ; i++) cin >> mid[i];
build(0,n-1,0,n-1);
int root = hou[n-1];
bfs(root);
}