4.12每日一题之美国血统(洛谷c++)|前序中序转后序

🍄前言

大家好哇,我是一勺黑猫,可以叫我小勺。今天是每日一题的第十二天,欢迎更多小伙伴加入到我们的打卡计划中,希望和你们在学习算法的路上一起进步~

🙎作者简介:一个正在努力学算法和后端的大三girl

⏳每日一题打卡地:高校算法学习社区

🎈联系方式:157543570(qq)

💨往期请看:小勺的每日一题https://blog.csdn.net/xingziyy/category_11731303.html


🍄今日题目

P1827 [USACO3.4] 美国血统 American Heritage - 洛谷 | 计算机科学教育新生态

🌰思路:本题用到树的前序中序转后序算法。假设你已经知道怎么由前序中序构建一棵二叉树,并后序遍历这棵树。那怎么用算法实现呢?

实际上,我们不需要创建出二叉树再遍历,而是通过递归直接输出就好了。我们需要一个函数post(int index,int l,int r),其中index表示每次遍历的根节点在前序序列中的位置,l和r表示遍历中序序列的范围。

初次遍历时,我们应该让index=0,l=0,r=in.length()-1,因为前序序列的第一个元素 是整棵树的根节点,遍历范围是整颗二叉树,如下图:

函数中要做什么呢?由于后序遍历是左、右、根的顺序,所以我们应该先递归调用此函数,分别遍历左子树和右子树,最后输出根节点的值。

基于此,我们的任务就是找到函数的参数:左右子树的根节点及其范围

根据下图,我们容易发现,如果找到根节点在中序序列中的位置i,就可以确定树的左子树和右子树的范围:[l,i-1],[i+1,r]。同样的,可以发现,在前序序列中,左子树的根节点是index+1,右子树的根节点是index+(i-l)+1。找到这些信息,我们就可以遍历左右子树啦(如果记不住范围的话,不妨在写代码时画一画,就不用死记硬背了~)

还有一点需要注意的是函数的结束条件。当l>r时,说明当前子树是空树,直接返回就好了。

 

🌰AC代码:

#include<iostream>
using namespace std;

//中序和前序序列
string in,pre;

void post(int index,int l,int r){
    if(l>r)
        return;

    //查找前序根节点在中序中的位置
    int i=l;
    while(i<r&&in[i]!=pre[index]) i++;

    post(index+1,l,i-1);       //左子树
    post(index+i-l+1,i+1,r);    //右子树
    cout<<pre[index];        //输出根
}

int main(){
    cin>>in>>pre;
    post(0,0,in.length()-1);
    return 0;
}

第一次画图用的ps,着实费了好大的劲qaq,如果有好用的画图软件可以推荐给我😘

看完如果让你有一丝收获,球球给一个三连支持!!!感谢大家

  • 44
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 30
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值