American Heritage美国血统
题目描述
农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。
他把他的奶牛们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。
你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。
(你可能已经知道你可以在知道树的两种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。
1 2 3 4 5 6 7 8 | C / \ / \ B G / \ / A D H / \ E F |
树的中序遍历是打印左子树,根和右子树;树的前序遍历是打印根,左子树和右子树;树的后序遍历是打印左子树,右子树和根。
输入给出前序遍历和中序遍历,求出后序遍历
输入格式
第一行: 树的中序遍历
第二行: 同样的树的前序遍历
输出格式
单独的一行表示该树的后序遍历。
分析:
算法:递归
思路:这道题我们主要是根据二叉树前/中/后遍历来如说(具体怎样遍历题目上已经讲解)。
因为告诉我们两种遍历结果,所以我们的递归就可以从这两种递归入手——用l,r,l1,r1来表示两种遍历方式所递归到的区间(左子树或右子树)。
我们先寻找到所在子树的根节点,再通过根节点来递归其对应的左右子树,在找出其左右子树对应的根节点,再递归其对应的左右子树,在……
但这道题显然不是让我们求出这可树原来的样子,是求出后序遍历。
既然这样,我们就得有一个先后顺序——因为后序遍历是左右根,我们就需要遍历左子树,再遍历右子树,最后加上根节点。只有这样才能求出后序遍历。
#include<bits/stdc++.h>
using namespace std;
char tr[100001]={};//用来记录后序
int a[201]={};
int n=0;
string s1,s2;//s1是中序,s2是前序
void dfs(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])
{
dfs(l,i-1,l1+1,l1+i-l);//先累加左子树
dfs(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];
}
dfs(1,s1.size(),1,s2.size());
for (int i=1;i<=n;i++) cout<<tr[i];
return 0;
}
分析:
例:中序s1=ABEDFCHG 前序s2=CBADEFHG
(我们已知前序的第一个就是最中间的结点)
l 和 l1 都是重1开始
s1 从 i=1 开始一个一个与s2 的 l1 匹配 :这里我们可以知道当 i=6 的时候匹配成功
后面开始先累加左子树
再对左子树 S1 的 1~i-1 中找与 S2 的 l1+1 匹配的 这样一直递归下去
后面对右子树一样的操作
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效