数据结构1-2 P1827美国血统

题目描述

  给出一棵二叉树的中序遍历和前序遍历, 求出这棵二叉树的后序遍历。

输入格式

第一行: 树的中序遍历

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

ABEDFCHG

CBADEFGH

输出格式 

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

AEFDBHGC

题目分析: 首先要了解二叉树三种遍历的定义, 前序遍历: 首先访问根结点, 然后遍历左子树, 最后遍历右子树。中序遍历: 首先遍历左子树, 然后访问根结点, 最后遍历右子树。后序遍历: 首先遍历左子树, 然后遍历右子树, 最后访问根结点。

  从以上对遍历的定义我们可以知道: 当前序遍历已知的情况下, 可以得到一棵二叉树的根结点——即为前序遍历的第一个元素。然后在中序遍历中找到根结点代表的元素, 往左便找到了左子树, 往右便找到了右子树 。但如何确定具体的算法呢?想一想二叉树遍历的过程, 本质上是深度优先搜索(DFS), 也就是递归的方式。所以可以自然地想到用递归算法进行求解。再根据后序遍历的定义: 先递归左子树, 再递归右子树, 最后访问根结点即可求得这棵二叉树的后序遍历

  本题递归的核心在于找到左子树的前序、中序遍历的左右端点, 右子树的前序、中序遍历的左右端点(分别把前序遍历的左右端点记为l_{1},r_{1}, 中序遍历的左右端点记为l_{2},r_{2}, 接下来会用样例的这棵二叉树进行分析:

 首先找到根结点"C"(图中标注了root), 在中序遍历中, "C"左边的"ABEDF"为左子树, 右边的"HG"为右子树。然后确定左子树前序遍历的左端点, "C"的右边为"B", 是第一个在左子树中的元素, 所以左端点l_{1}=l_{1}+1; 接下来确定右端点。在中序遍历中"C"的旁边是"F", 对应的下标为i-1, 所以距离=i-1-l_{2}+1=i-l_{2}, 所以右端点r_{1}=l_{1}+i-l_{2} 。

  接下来确定左子树中序遍历的左端点, 由于左端点l_{2}本身就在左子树内, 所以不变, 而右端点r_{2}=i-1 。

然后确定右子树前序遍历的左端点, 在中序遍历中, "C"的右边是"H", 对应的下标为i+1, 所以距离=i+1-l_{2}, 所以左端点l_{1}=l_{1}+i+1-l_{2}, 右端点r_{1}不变。同理可得: l_{2}=i+1r_{2}不变。

以下是代码

#include<bits/stdc++.h>
using namespace std;
string in_order,pre_order;
void build(int l1,int r1,int l2,int r2){
    int i;
    if(l1>r1||l2>r2) return;
    for(i=l2;i<=r2;i++)
        if(in_order[i]==pre_order[l1]){
            build(l1+1,l1+i-l2,l2,i-1);
            build(l1+i+1-l2,r1,i+1,r2);
            cout<<in_order[i];
        }
}
int main(){
    int length;
    cin>>in_order>>pre_order;
    length=in_order.size();
    build(0,length-1,0,length-1);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值