Uva 536 Tree Recovery
题意:输入一棵树的的前序遍历结果,以及中序遍历结果,求此树的后续遍历结果。
思路:因为在后续遍历中,先访问左结点,再访问右结点,最后采访问根结点。那么根据前续遍历可以在中序遍历中找到树根,将其分为左右子树,再递归找子树的数根,将其分为左右子树,得到数根的顺序刚好是后续遍历的逆顺序。
如:DBACEGF ABCDEFG
第一步:前续先访问了D,所以把中序分为ABC 和 EFG 两部分,分别对应左子树和右子树
第二步:EGF 和 EFG 先访问了E, 此时此棵树只有有右子树
第三步:GF 和 FG 则先得到G, 再得到F
第四步:BAC 和 ABC 先得到B, 分为A,C两棵子树
第五步:先访问C再访问A
将得到结点的顺序倒置,得:ACBFGED
/*
UvaOJ 536
Emerald
Sat 13 Jun 2015
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
string preOrder, inOrder;
vector <char> postOrder;
void FindSub( int L1, int R1, int L2, int R2 ) {
if( R1 < L1 ) {
return ;
}
postOrder.push_back( preOrder[ L1 ] );
int p = L2;
while( inOrder[ p ] != preOrder[ L1 ] ) {
p ++;
}
int cnt = p - L2;
if( p!=R2 ) { // right subtree first
FindSub( L1+cnt+1, R1, p+1, R2 );
}
if( p!=L2 ) {
FindSub( L1+1, L1+cnt, L2, p-1 );
}
}
int main() {
while( cin >> preOrder >> inOrder ) {
postOrder.clear();
FindSub( 0, preOrder.size()-1, 0, inOrder.size()-1 );
for( int i=postOrder.size()-1; i>=0; i -- ) {
printf("%c", postOrder[i] );
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号