题意:输入一棵树的的前序遍历结果,以及中序遍历结果,求此树的后续遍历结果。
思路:因为在后续遍历中,先访问左结点,再访问右结点,最后采访问根结点。那么根据前续遍历可以在中序遍历中找到树根,将其分为左右子树,再递归找子树的数根,将其分为左右子树,得到数根的顺序刚好是后续遍历的逆顺序。
如: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(" "); } return 0; }