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

news2024/12/28 20:38:55

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.coloradmin.cn/o/1031055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CRM软件系统维护客户的主要方法

客户的重要性&#xff0c;相信每一个做企业的人都非常清楚。为了维护好客户&#xff0c;很多企业都使用CRM客户管理系统&#xff0c;建立“以客户为中心”的经营理念&#xff0c;提高企业客户服务水平&#xff0c;进而在提高客户满意度的同时提高企业的盈利。那么&#xff0c;企…

ubuntu、linux in window安装docker教程

1、首先进入管理员权限。 2、更新软件源。 sudo apt update 3、安装一些依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common 4、为系统添加Docker的密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-k…

28.CSS 渐变圆文本动画

效果 源码 index.html <!doctype html> <html> <head><meta charset="utf-8"><title>Glowing Gradient Circle Text Animation</title><link rel="stylesheet" href="style.css"> </head> &l…

合同被篡改,被变更,被调换风险大?君子签电子合同有效化解

纸质合同签署文件类型多&#xff0c;签署量大&#xff0c;人为干预较多&#xff0c;合同被篡改&#xff0c;被变更&#xff0c;被调换风险大&#xff0c;难以防范和避免。 请注意&#xff0c;出现以下几个情况&#xff0c;代表你已经遭遇合同“调包计”了&#xff01; 1、合…

“undefined reference to XXX“问题总结

"undefined reference to XXX"问题总结 引言 我们在Linux下用C/C工作的时候&#xff0c;经常会遇到"undefined reference to XXX"的问题&#xff0c;直白地说就是在链接(从.cpp源代码到可执行的ELF文件&#xff0c;要经过预处理->编译->链接三个阶…

换台电脑python使用uiautomator2操作逍遥模拟器

前几天写了一篇文章python使用uiautomator2操作雷电模拟器_小小爬虾的博客-CSDN博客 今天用另外一个环境和模拟器再次测试。 环境如下&#xff1a;win7 sp1 64位&#xff1b;Python3.8.10&#xff1b;逍遥模拟器9.0.6&#xff1b;android版本9&#xff1b;逍遥模拟器自带adb版…

【数据结构】顺序表与ArrayList

作者主页&#xff1a;paper jie 的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVA数据结构》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精…

2023研究生数学建模D题思路代码 区域双碳目标与路径规划研究

D题思路代码 区域双碳目标与路径规划研究 完整解题思路可看视频&#xff1a; 2023华为杯研赛D题区域双碳目标与路径规划研究&#xff08;附代码全保姆教程&#xff09;_哔哩哔哩_bilibili​www.bilibili.com/video/BV1Cm4y157CH/?spm_id_from333.999.0.0 问题一&#xff1a;…

将序列中的每一行重复扩展为指定数量的行Series.repeat()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将序列中的每一行 重复扩展为指定数量的行 Series.repeat() [太阳]选择题 以下说法正确的是 import pandas as pd s1pd.Series([10, 25, 3]) s1.index [A, B, C] print(【显示】s1为&#xff…

超级好用的高效率记笔记软件

高效率的记录学习笔记&#xff0c;可以帮助我们日后进行知识的回顾、学习及分享&#xff0c;对于有记录学习笔记需求的学生来讲&#xff0c;在日常生活中找一款好用的记录学习笔记的非常有必要的&#xff0c;手机作为一款比较便携的工具&#xff0c;在手机上安装笔记类工具&…

家居行业如何借助AI营销数智化转型?《2023 家居行业AI营销第一课(重庆站)》给你答案

商务部将2023年定为“消费提振年”。作为仅次于汽车消费的家庭第二大消费支出&#xff0c;家居产业的高质量发展与扩大内需提振消费息息相关。随着今年利好政策不断发布&#xff0c;家居建材行业的市场环境及消费潜力得到大幅度改善。 随着ChatGPT等新技术的出现与消费需求升级…

安全基础 --- nodejs沙箱逃逸

nodejs沙箱逃逸 沙箱绕过原理&#xff1a;沙箱内部找到一个沙箱外部的对象&#xff0c;借助这个对象内的属性即可获得沙箱外的函数&#xff0c;进而绕过沙箱 前提&#xff1a;使用vm模块&#xff0c;实现沙箱逃逸环境。&#xff08;vm模式是nodejs中内置的模块&#xff0c;是no…

【腾讯云】打造未来智能应用的基石:腾讯混元大模型

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

vue-cli-service build 不同环境的配置

目录 &#x1f91c; 背景 &#x1f91c; vue-cli-service介绍 &#x1f91c; 环境变量和模式 &#x1f91c; 配置不同模式 &#x1f91c;index.html使用环境变量 &#x1f91c; 验证 &#x1f91c; 参考资料 &#x1f91c; 背景 在项目部署时&#xff0c;我们需要在测试…

如何通过文件自动备份软件进行自动化备份?

​为什么要使用文件自动备份软件 有一位做客户资料保管登记的朋友&#xff0c;每天会在电脑上录入很多新的客户资料&#xff0c;并需要进行相关维护。比如删掉一些取消合作的客户&#xff0c;或者添加一些备注等等。对于像他这种工作性质的人来说&#xff0c;很需要一个可以…

c++ this指针与空指针调用类方法以及常函数

一、this指针 说明 1、c的成员变量与成员内函数是分开存储 2、每一个非静态成员函数只会诞生一份函数实例&#xff0c;多个同类型的队形公用的是同一份成员函数的代码 3、this指向调用这一份成员函数代码的对象实例 4、this是一个隐藏的指向对象实例的一个指针,无需定义直接使…

使用Vue-cli构建spa项目及结构解析

一&#xff0c;Vue-cli是什么&#xff1f; 是一个官方发布的Vue脚手架工具&#xff0c;用于快速搭建Vue项目结构&#xff0c;提供了现代前端开发所需要的一些基础功能&#xff0c;例如&#xff1a;Webpack打包、ESLint语法检查、单元测试、自动化部署等等。同时&#xff0c;Vu…

百度SEO不稳定的原因及解决方法(百度SEO不稳定因素的5大包括)

百度SEO优化不稳定介绍&#xff1a;蘑菇号-www.mooogu.cn 随着百度SEO算法的不断变化和升级&#xff0c;许多网站的SEO排名经常出现不稳定的情况&#xff0c;这种情况在一定程度上影响了网站的流量和排名&#xff0c;导致网站的质量评分降低。因此&#xff0c;深入分析百度SEO…

ubuntu的root用户修改密码失败

解决如下&#xff1a; 查看文件属性是否有a或i lsattr /etc/group /etc/passwd /etc/shadow 移除a和i的属性权限 chattr -ai /etc/group /etc/passwd /etc/shadow 再次使用passwd进行修改密码&#xff0c;就成功了

时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测

时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测 目录 时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预…