二叉树的构建(已知两个遍历结果,来构建二叉树)

2024-05-03 14:28

本文主要是介绍二叉树的构建(已知两个遍历结果,来构建二叉树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、从前序与中序遍历构建二叉树

方法一:再构建两个数组,进行存储分割的左右子树

方法二:哈希映射

二、从中序和后序遍历构造二叉树


一、从前序与中序遍历构建二叉树

假如有这样一棵二叉树,它的前序遍历为1 2 4 5 3 6 ,中序遍历为 4 2 5 1 6 3

图文分析:

根节点为前序遍历的第一个节点

然后通过前序遍历得到的根节点以及形成的中序遍历结构进行左右子树划分

代码演示:

方法一:再构建两个数组,进行存储分割的左右子树

class Solution {
public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if (preorder.size() == 0) return NULL;int pos = 0, n = preorder.size();while (inorder[pos] != preorder[0])pos += 1; //找到中序遍历中的根节点位置TreeNode* root = new TreeNode(preorder[0]);vector<int> preArr;// 存储前序遍历的结果vector<int> inArr; // 存储中序遍历的结果//获得根节点的左子树for (int i = 1; i <= pos; i++) preArr.push_back(preorder[i]); //前序遍历左子树的结果for (int i = 0; i <= pos; i++) inArr.push_back(inorder[i]); //中序遍历左子树的结果root->left = buildTree(preArr, inArr);preArr.clear();inArr.clear();//获得根节点的右子树for (int i = pos + 1; i < n; i++) preArr.push_back(preorder[i]); //前序遍历右子树的结果for (int i = pos + 1; i < n; i++) inArr.push_back(inorder[i]); //中序遍历右子树的结果root->right = buildTree(preArr, inArr);return root;}
};

方法二:哈希映射

这个方法更便于我们找到根节点所在中序遍历的位置

class Solution {
private:unordered_map<int, int> pos;public:TreeNode* dfs(const vector<int>& preorder, const vector<int>& inorder, int pl, int pr, int il, int ir) {if (pl > pr) return nullptr;// 前序遍历中的第一个节点就是根节点int k = pos[preorder[pl]]; // 在中序遍历中定位根节点// 先把根节点建立出来TreeNode* root = new TreeNode(preorder[pl]);int len = k - il;// 得到左子树中的节点数目// 递归地构造左子树,并连接到根节点// 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素root->left = dfs(preorder, inorder, pl + 1, pl + len, il, k - 1);// 递归地构造右子树,并连接到根节点// 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素root->right = dfs(preorder, inorder, pl + len + 1, pr, k + 1, ir);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int n = preorder.size();// 构造哈希映射,帮助我们快速定位根节点for (int i = 0; i < n; ++i) {pos[inorder[i]] = i;}return dfs(preorder, inorder, 0, n - 1, 0, n - 1);}
};

二、从中序和后序遍历构造二叉树

图文演示:

假如有这样一棵二叉树,它的后序遍历为4 5 2 6 3 1 ,中序遍历为 4 2 5 1 6 3.

代码演示:哈希映射

class Solution {
public:unordered_map <int, int>pos;TreeNode* dfs(vector<int>& inorder, vector<int>& postorder, int il, int ir, int pl, int pr) {if (il > ir) return NULL;int k = pos[postorder[pr]];//中序遍历确定根位置TreeNode* root = new TreeNode(postorder[pr]); //创立根节点root->left = dfs(inorder, postorder, il, k - 1, pl, pl + k - 1 - il);root->right = dfs(inorder, postorder, k + 1, ir, pl + k - il, pr - 1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int n = inorder.size();for (int i = 0; i < n; i++) {pos[inorder[i]] = i;}return dfs(inorder, postorder, 0, n - 1, 0, n - 1);}
};

三、根据前序和后序遍历构造二叉树​​​​​​

这个知前序和后序遍历构建的二叉树得到的二叉树不唯一

代码演示:(双指针法)

考虑到后序遍历的倒数第二个节点刚好为右节点。

class Solution {
public:int preIndex = 0, posIndex = 0;TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {TreeNode* root = new TreeNode(preorder[preIndex++]);if (root->val != postorder[posIndex]) root->left = constructFromPrePost(preorder, postorder);if (root->val != postorder[posIndex]) root->right = constructFromPrePost(preorder, postorder);posIndex++;return root;}
};

这篇关于二叉树的构建(已知两个遍历结果,来构建二叉树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956949

相关文章

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be