T236450 美国血统

农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。

你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。 这是在样例输入和 样例输出中的树的图形表达方式:

 

 

树的中序遍历是按照左子树,根,右子树的顺序访问节点。

树的前序遍历是按照根,左子树,右子树的顺序访问节点。

树的后序遍历是按照左子树,右子树,根的顺序访问节点。

 

输入格式

第一行: 树的中序遍历

第二行: 同样的树的前序遍历

输出格式

单独的一行表示该树的后序遍历。

 

输入输出样例

输入 #1
ABEDFCHG
CBADEFGH 
输出 #1
AEFDBHGC

思路:因为题目告诉了我们两种遍历的结果,所以从两种递归入手,用l,r,l1,r1来表示两种遍历方式所递归到的左子树或右子树。
我们先寻找到所在子树的根节点,再通过根节点来递归对应的左右子树,再找出其左右子树的根节点,再递归对应的左右子树,重复如此。
但是这道题并非让我们求出树原来的样子,是求出后序遍历,所以我们先需要遍历左子树,再遍历右子树,然后加上根节点。

三种遍历的性质:

先序遍历:

①先序遍历第一个节点是整棵树G的根节点,第二个节点是他的左儿子

②对于先序遍历中的任意一个编号为m的节点,如果已知以这个节点为根节点的左子树结点个数为l,右子树的结点个数为r,那么左子树在先序中的[m+1,m+l],右子树在先序中的[m+l +1,m+l +r]

中序遍历:

对于中序遍历中的任意一个编号为m的节点,如果已知以这个节点为根节点的左子树结点个数为l,右子树的结点个数为r,那么左子树在中序中的[m-l,m-1],右子树在中序中的[m+1,m+r]

后序遍历:

对于后序遍历中的任意一个编号为m的节点,如果已知以这个节点为根节点的左子树结点个数为l,右子树的结点个数为r,那么左子树在后序中的[m-r-l,m-r-1],右子树在后序中的[m-r,m-1]

复制代码
#include<bits/stdc++.h>
using namespace std;
char tr[100000]={};
int a[200]={};
int n=0;
string s1,s2;
void aaa(int l,int r,int l1,int r1){
     if (l==r) {tr[++n]=s1[l];return;}
     for (int i=l;i<=r;i++)
       if (s1[i]==s2[l1]){
           aaa(l,i-1,l1+1,l1+i-l);
           aaa(i+1,r,l1+i-l+1,r1);
           tr[++n]=s1[i];
           break;
       }
}
int main(){
    cin>>s1>>s2;
    for (int i=s1.size();i>=1;i--)
    s1[i]=s1[i-1],s2[i]=s2[i-1];
    aaa(1,s1.size(),1,s2.size());
    for (int i=1;i<=n;i++)
    cout<<tr[i];
    return 0;
}
复制代码

 

posted @   嗨嗨害  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示