バイナリツリーは、空またはルートRからなり、2つの互いに素のバイナリツリーが左右サブツリーと呼ばれる頂点の有限集合です。バイナリツリーの頂点が体系的に横断または注文することができる最も重要な3つの方法があります。彼らは前順、INORDERおよび後順です。Tは、ルートRとサブツリーT1、T2との二分木とします。
Tの頂点の先行順走査で、我々は、ルートrは先行予約でT2の頂点次いで、先行順にT1の頂点を訪れる続い訪れます。
Tの頂点のINORDERトラバーサルでは、我々は、INORDERにINORDERにおけるT2の頂点に続く、ルートrを、T1の頂点を訪れます。
Tの頂点の後順トラバーサルでは、我々は後順で、その後、後順にT2の頂点をT1の頂点を訪問し、最終的に我々は、rをご覧ください。
今、あなたは特定のバイナリツリーの前のシーケンスとINORDERシーケンスを与えられています。その後順のシーケンスを見つけるために試してみてください。
InputThe入力には、いくつかのテストケースが含まれています。各テストケースの最初の行は、単一の整数N(1 <= N <= 1000)、二分木の頂点の数を含んでいます。それぞれプレオーダー配列およびINORDER順序を示す2本のラインが続きます。あなたは、彼らが常に排他的なバイナリツリーに対応していると仮定することができます。
各テストケースOutputFor対応する後順のシーケンスを指定する単一の行を印刷します。
サンプルインプット
9
1 2 4 7 3 5 8 9 6
4 7 2 1 8 9 5 3 6
出力例
7 4 2 8 9 5 6 3 1
ご注文後、あなたに先行順走査とINORDERトラバーサル要求を与えます。
自然の先行順とINORDERから入手することができます:現在のルートによる最初のオーダーの最初のポイントは確かに借りサブツリーで、その後、
シーケンス内のノードを見つけ、その後、このノードノードは左のサブツリーの左に属し、右側の右部分木に属します。そして、再帰的にトラバース
この方法の一つ
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int mn=1010;
int n,g,a[mn],b[mn],c[mn];
void xia(int he,int ta,int &md)
{
int d=md;
if(he==ta)
{
c[++g]=a[d];
return ;
}
for(int i=he;i<=ta;i++)
{
if(b[i]==a[md])
{
if(he<=i-1&&md+1<=n) xia(he,i-1,++md);
if(i+1<=ta&&md+1<=n) xia(i+1,ta,++md);
break;
}
}
c[++g]=a[d];
return ;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int j=1;j<=n;j++)
scanf("%d",&b[j]);
g=0;
int md=1;
xia(1,n,md);
for(int i=1;i<n;i++)
printf("%d ",c[i]);
printf("%d\n",c[n]);
}
}
方法二
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int mm=1e3+10;
int a[mm],b[mm];
int n;
void dfs(int x,int y,int root)
{
int i;
if(x>y) return ;
for(i=x;i<=y;i++)
if(a[root]==b[i])
break;
dfs(x,i-1,root+1);
dfs(i+1,y,root+(i-x)+1);
printf("%d%c",a[root],root==1?'\n':' ');
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
dfs(1,n,1);
}
}