前序+中序------>后序
取前序的第一个节点,一定是根节点,在中序中找对应的下标m,将中序序列分为[l,m-1]和[m+1, r]两个子序列,分别对应左子树和右子树,继续取第二个前序节点,应该是左子树的根节点(如果左子树存在),在[l, m-1]中找到其下标,继续二分…
中序+后序------>前序
后序的最后的节点一定是根节点,为方便,可先将其反转,与上面同理
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int maxn = 55;
char pre[maxn], inner[maxn], post[maxn];
char res[maxn];
int pos, idx;
//前序+中序------>后序
void pre_inner_2_post(int pos, int l, int r){
if(l > r) return;
if(l == r){
res[idx++] = pre[pos];
return;
}
int k;
for(int i = l; i <= r; ++i){
if(inner[i] == pre[pos]){ k = i; break;}
}
pre_inner_2_post(pos+1, l, k-1);
pre_inner_2_post(pos+k-l+1, k+1, r);
res[idx++] = pre[pos];
}
void inner_post_2_pre(int pos, int l, int r){
if(l > r) return;
if(l == r){
res[idx++] = post[pos];
return;
}
int k;
for(int i = l; i <= r; ++i){
if(inner[i] == post[pos]){ k = i; break;}
}
res[idx++] = post[pos];
inner_post_2_pre(pos+r-k+1, l, k-1);
inner_post_2_pre(pos+1, k+1, r);
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%s", pre);
scanf("%s", inner);
printf("%s %s\n",pre,inner);
idx = 0;
pre_inner_2_post(0, 0, strlen(inner)-1);
printf("pre + inner -----> post: %s\n", res);
scanf("%s", inner);
scanf("%s", post);printf("%s\n",post);
int len = strlen(post);
for(int i = 0; i < len/2; ++i) swap(post[i], post[len-1-i]);
printf("%s\n", post);
idx = 0;
inner_post_2_pre(0, 0, len-1);
printf("inner + post -----> pre: %s\n", res);
fclose(stdin);
return 0;
}