P1827 [USACO3.4] 美国血统 American Heritage(前序 + 中序 生成后序)

P1827 [USACO3.4] 美国血统 American Heritage(前序 + 中序 生成后序)

一、前言

二叉树入门题。涉及到树的基本知识、树的结构、树的生成。
本文从会从结构,到完成到,优化。

二、基础知识

Ⅰ、二叉树的遍历

  • 前序遍历: 左右
  • 中序遍历:
  • 后序遍历: 左右

通过上面的观察,可得根在那,就是什么方式的遍历

Ⅱ、二叉树的结构

二叉树的结构:节点值 + 左节点指针 + 右节点指针

// c++的结构体写法
struct node {char val;node *left;node *right;node() : val(0), left(nullptr), right(nullptr){}node(int val) : val(val), left(nullptr), right(nullptr){}node(int val, node *left, node *right) : val(val), left(left), right(right){}
};
// c语言结构体写法
struct node {char val;struct node *left;struct node *right;node() : val(0), left(NULL), right(NULL){}node(int val){val = val;left = NULL;right = NULL;{node(int val, struct node *left, struct node *right) {val = val;left = left;right = right;}
};

三、直接思路

通过 前序 + 中序 直接生成 树。然后再前序遍历(可以过)
现在的问题,就变成了。怎么生成树了。
估计大家在学习数据结构,二叉树这一章节中。老师肯定讲过手写这个题(通过前序或后序找到根节点,然后把中序分成两部分,左子树,右子树)。但是现在怎么把他变成代码呢?

#include <iostream>
using namespace std;struct node {char val;node *left;node *right;node() : val(0), left(nullptr), right(nullptr){}node(char x) : val(x), left(nullptr), right(nullptr){}node(char x, node *left, node *right) : val(x), left(left), right(right){}
};
/*
s1 中序
[inorderBegin, inorderEnd)
s2 前序
[preorderBegin, preorderEnd)
上述就是现在树的范围
再分割子树的范围就可以了
明白范围!!!左端点可取,右端点不可取
*/
node *traversal(string s1, int inorderBegin, int inorderEnd, string s2, int preorderBegin, int preorderEnd) {if (preorderEnd == preorderBegin) return nullptr;char val = s2[preorderBegin];node *root = new node(val);if (preorderEnd - preorderBegin == 1) return root;int delimiterIndex; // 左右子树的分割点for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {if (s1[delimiterIndex] == val) break;}// 左子树// 中序int leftInorderBegin = inorderBegin;int leftInorderEnd = delimiterIndex;// 前序int leftPreorderBegin = preorderBegin + 1;int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBegin;// 右子树int rightInorderBegin = delimiterIndex + 1;int rightInorderEnd = inorderEnd;int rightPreorderBegin = preorderBegin + delimiterIndex - inorderBegin + 1;int rightPreorderEnd = preorderEnd;root->left = traversal(s1, leftInorderBegin, leftInorderEnd, s2, leftPreorderBegin, leftPreorderEnd);root->right = traversal(s1, rightInorderBegin, rightInorderEnd, s2, rightPreorderBegin, rightPreorderEnd);return root;
}void dfs(node *root) {if (!root) return ;dfs(root->left);dfs(root->right);cout << root->val;
}int main() {node *tree;string s1, s2;cin >> s1 >> s2;tree = traversal(s1, 0, s1.size(), s2, 0, s2.size());dfs(tree);return 0;
}

在这里插入图片描述

四、优化

通过上面可以发现,他在生成树的过程中,就是经行的后续遍历。所以不用直接生成树。

#include <iostream>
using namespace std;void traversal(string s1, int inorderBegin, int inorderEnd, string s2, int preorderBegin, int preorderEnd) {if (preorderEnd == preorderBegin) return;char val = s2[preorderBegin];int delimiterIndex; // 左右子树的分割点for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {if (s1[delimiterIndex] == val) break;}// 左子树// 中序int leftInorderBegin = inorderBegin;int leftInorderEnd = delimiterIndex;// 前序int leftPreorderBegin = preorderBegin + 1;int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBegin;// 右子树int rightInorderBegin = delimiterIndex + 1;int rightInorderEnd = inorderEnd;int rightPreorderBegin = preorderBegin + delimiterIndex - inorderBegin + 1;int rightPreorderEnd = preorderEnd;traversal(s1, leftInorderBegin, leftInorderEnd, s2, leftPreorderBegin, leftPreorderEnd);traversal(s1, rightInorderBegin, rightInorderEnd, s2, rightPreorderBegin, rightPreorderEnd);cout << val;
}int main() {string s1, s2;cin >> s1 >> s2;traversal(s1, 0, s1.size(), s2, 0, s2.size());return 0;
}

五、相关题目

  • LeetCode 105. 从前序与中序遍历序列构造二叉树
  • LeetCode 106. 从中序与后序遍历序列构造二叉树

六、最后

创作不易,留个赞,鼓励一下把!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/138657.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA开发工具技巧

1.1 IDEA相关插件 idea插件下载地址&#xff1a;https://plugins.jetbrains.com/ 开发必装插件&#xff1a; &#xff08;1&#xff09; 快速查找api接口 RestfulTool 插件&#xff0c;推荐指数⭐⭐⭐⭐⭐ [RestfulTool搜索插件使用详解](https://blog.csdn.net/weixin_450147…

vue3硅谷甄选01 | 使用vite创建vue3项目及项目的配置 环境准备 ESLint配置 prettier配置 husky配置 项目集成

文章目录 使用vite创建vue3项目及项目的配置1.环境准备2.项目配置ESLint校验代码工具配置 - js代码检测工具1.安装ESLint到开发环境 devDependencies2.生成配置文件:.eslint.cjs**3.安装vue3环境代码校验插件**4. 修改.eslintrc.cjs配置文件5.生成ESLint忽略文件6.在package.js…

工作应当有挑战

有挑战 才能有所成长 正所谓人到山前必有路 是挑战 一般就会有未知 未知往往伴随着困难 有困难 并不可怕&#xff0c;也不必自我抱怨&#xff0c;自我抱怨只会陷入无尽的精神内耗 我们只要做好自己 困难就会迎刃而解 如果自己的获得 没有达到自己的期望 其实那也不必气馁 再…

【计算机网络】IP协议

文章目录 TCP与 IP之间的关系IP地址的认识协议报头格式1. 报头和有效载荷如何分离&#xff1f;2. 8位协议3. 4位版本4. 8位服务类型5. 16位总长度6. 8位生存时间 TTL 网段划分IP地址的划分 子网划分CIDR的提出如何理解CIDR TCP与 IP之间的关系 如&#xff1a;假设 你上高中时&…

无聊的一篇博客(如何通过路由器登陆页对固定机器进行网速干扰,如何帮熊孩子戒网瘾)

1. 路由器登陆页面&#xff0c;按钮解析&#xff0c;获取按钮。 2. JavaScript与上传的脚本。 // 获取要点击的按钮A和按钮B元素var isRunning true; // 初始状态为false// 定义一个函数来模拟点击按钮A和按钮B function clickButtons() {if (isRunning) {// 随机生成一个延时…

QTday2

完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两个按钮…

clion 安装 boost 库

不保证有效&#xff0c;很多教程的 cmake 都是带版本号的 1、先安装 boost 库 brew install boost 2、clion 工程的 CMakeLists.txt 文件中间添加两行&#xff0c;加在 add_executable 上面 find_package(Boost) include_directories(${Boost_INCLUDE_DIRS}) 我的源文件 …

2023华为杯研究生数学建模竞赛选题建议+初步分析

如下为C君的2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议初步分析 2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议 提示&#xff1a;DS C君认为的难度&#xff1a;CE<D<F&#xff0c;开放度&#xff1a;CDE<F。 华为专项…

分布式运用之企业级日志ELFK+logstash的过滤模块

一、ELFK集群部署&#xff08;FilebeatELK&#xff09; 在搭建ELK的基础上安装Filebeat服务&#xff0c;Filebeat服务可以布置在以下任意一台主机&#xff0c;本次实验将布置在apache服务器的节点上 步骤一&#xff1a;安装 Filebeat&#xff08;在apache节点操作&#xff09…

【GIS】地理坐标系WGS84、GCJ-02、BD-09、GCS2000

地理坐标系又可分为 参心坐标系 和 地心坐标系&#xff0c;常见的参心坐标系北京54、西安80&#xff0c;常见的地心坐标系有WGS84、GCJ-02、BD-09、GCS2000 地心坐标系 WGS84&#xff08;World Geodetic System 1984&#xff09; WGS84是为 GPS 全球定位系统建立的坐标系统&…

python随手小练

题目&#xff1a; 使用python做一个简单的英雄联盟商城登录界面 具体操作&#xff1a; print("英雄联盟商城登录界面") print("~ * "*15 "~") #找其规律 a "1、用户登录" b "2、新用户注册" c "3、退出系统&quo…

PIL或Pillow学习1

PIL&#xff08; Python Imaging Library&#xff09;是 Python 的第三方图像处理库&#xff0c;由于其功能丰富&#xff0c;API 简洁易用&#xff0c;因此深受好评。 自 2011 年以来&#xff0c;由于 PIL 库更新缓慢&#xff0c;目前仅支持 Python 2.7 版本&#xff0c;这明显…

react实现列表滚动组件

1.需求 在开发项目的时候&#xff0c;从服务端获取到数据列表后&#xff0c;展示给用户看&#xff1a;需要实现数据自动滚动效果&#xff0c;怎么实现呢&#xff1f;如下图所示&#xff1a; 2.实现 把上面需要实现的功能写成一个组件&#xff0c;页面直接调用该组件即可&#x…

计算机视觉与深度学习-经典网络解析-AlexNetZFNetVGGGoogLeNetResNet[北邮鲁鹏]

目录标题 参考文章LeNet5AlexNet参考文章AlexNet模型结构AlexNet共8层&#xff1a;AlexNet运作流程 简单代码实现重要说明重要技巧主要贡献 ZFNet主要改进减小第一层卷积核将第二、第三个卷积层的卷积步长都设置为2增加了第三、第四个卷积层的卷积核个数 VGG参考VGG网络贡献使用…

锐捷交换机vlan隔离(wifi段仅能访问外网,和内网隔离)

因为公司的wifi段&#xff0c;未做隔离&#xff0c;无意间上了网&#xff0c;发现能访问内网网段&#xff0c;这里内网是10、20段&#xff0c;管理网段是100段&#xff0c;于是做了和内网的vlan隔离。 拓朴如下&#xff0c;所有vlan的网关都起在核心上&#xff0c;核心上起了DH…

批量调整视频饱和度和色度,提升你的视频剪辑效率!

作为一名视频剪辑师&#xff0c;你是否经常为如何高效地调整多个视频的饱和度和色度而烦恼&#xff1f;现在&#xff0c;我们为你提供了一种简单、快速、准确的方法&#xff0c;帮助你轻松解决这个问题&#xff01; 首先我们要进入好简单批量智剪&#xff0c;并在左侧的板块栏…

iPhone15拉胯,国产手机用折叠屏大反攻!

文 | 智能相对论 作者 | K星 iPhone偷懒式的15代机型发布&#xff0c;让市场大跌眼镜&#xff0c;虽然在莫名的宗教虔诚下依旧卖得很好&#xff0c;但苹果走下神坛之巅已经板上钉钉。 但是&#xff0c;苹果从最高处摔落&#xff0c;却依旧在神坛之上&#xff0c;iPhone15拉胯…

K8s的网络——Underlay和Overlay网络

0. 基础知识 1&#xff09;网络7层基础知识 在网络7层协议基础里&#xff0c; 第一层物理链路&#xff1b;第二层是数据链路层&#xff0c;在第一层的基础上引入MAC地址做数据转发。MAC地址在局域网内具有唯一性&#xff0c;主机A发送数据时&#xff0c;会向局域网内进行广播…

九、【漏洞复现】Struts 2 远程代码执行漏洞s2-046(CVE-2017-5638)

九、【漏洞复现】Struts 2 远程代码执行漏洞s2-046&#xff08;CVE-2017-5638&#xff09; 9.1、漏洞原理 Struts 2是一个基于MVC设计模式的Web应用框架&#xff0c;本质上相当于一个Servlet,在MVC设计模式中&#xff0c;Struts2作为控制器来建立模型与视图进行数据交互。 攻…

GE IS420UCSCH2A-C-V0.1-A模拟量输入模块

GE IS420UCSCH2A-C-V0.1-A 模拟量输入模块是一种用于数据采集和监测的电子模块&#xff0c;通常应用于工业控制系统、监测设备和自动化系统中。以下是可能与该模拟量输入模块相关的一些产品特点&#xff1a; 多通道输入&#xff1a; GE IS420UCSCH2A-C-V0.1-A 模拟量输入模块通…