重建二叉树

    二叉树是我们学习数据结构阶段一个重要的知识点,二叉树又被分为满二叉树,完全二叉树和其它三种来学习,所谓的满二叉树是指我们的二叉树的每一个非叶子节点一定含有左孩子和右孩子,而完全二叉树则是指我们的树的叶子节点必须连续的分布在树的左边。

    今天,我们来探索一下如何在知道二叉树前序遍历顺序及中序遍历顺序来重建二叉树

    首先,重建我们的二叉树,必须要找到根节点,那么根节点应该如何找到呢。如下图所示,根结点必定是我们前序遍历数组的首元素。在知道了根节点的情况下,我们就可以在我们的中序遍历序列里找到我们需要的根节点所在。只要有了根节点的位置,我们很容易就可以确定左树节点个数,以及右树的节点个数。而我们很清楚,在二叉树这里我们大多采用递归来解决子问题,所以显而易见的,我们将根节点的左子树和右子树转换成为子问题来解决更加容易理解。

wKioL1cp4Ljgs5RrAAALCZNRp2Y032.png

    下面我给出了本题的详细代码以及注释j_0046.gif

struct BinaryTreeNode
{
	int _value;
	BinaryTreeNode *_left;
	BinaryTreeNode *_right;
	BinaryTreeNode(const int& x = 0) :_value(x), _left(NULL), _right(NULL)
	{}
};
class BinaryTree
{
private:
	BinaryTreeNode *_root;
public:
	BinaryTree()
	{}
	BinaryTree(int *PreOrder, int *InOrder,int size)
	{
		if (!PreOrder || !InOrder || size <= 0)
			return;
		_root = _CreateTree(PreOrder, PreOrder + size - 1, InOrder, InOrder + size - 1);
	}
private:
	BinaryTreeNode* _CreateTree(int *Pre,int *endPre,int *In,int *endIn)
	{
		//构造当前根节点root 
		int RootValue = Pre[0];
		BinaryTreeNode *root = new BinaryTreeNode(RootValue);
		
		//当走到最后一个元素
		if (Pre == endPre)
		{
			//如果中序也走到了最后一个节点
			//最后一个节点相等说明最后一个节点是一个右分支
			if (In == endIn && *Pre == *In)
				return root;
		}

		//在中序遍历中找到根节点
		int *rootIn = In;
		while (rootIn <= endIn && *rootIn != RootValue)
		{
			//当它等于前序首元素时表示为中序的根节点
			++rootIn;
		}
		//找到之后计算出左子树的节点数
		int leftLen = rootIn - In;

		//找出前序里左子树的构造区间
		int *PreLeftEnd = Pre + leftLen;
		if (leftLen > 0)
		{
			//构造左子树
			root->_left = _CreateTree(Pre + 1, PreLeftEnd  , In, rootIn - 1);
		}

		if (leftLen < endPre - Pre)
		{
			//构造右子树
			root->_right = _CreateTree(PreLeftEnd + 1, endPre, rootIn + 1, endIn);
		}
		return root;

	}
};
int main()
{
	int Pre[] = { 1, 2, 4, 5, 3, 6 };
	int In[] = { 4, 2, 5, 1, 6, 3};
	BinaryTree tree(Pre, In, sizeof(Pre) / sizeof(Pre[0]));
	getchar();
	return 0;
}

    如果实在不能理解建议在纸上将整个过程整理一遍,相信这样就会对树的建立以及递归的算法有深刻的理解,显然博主就经常这么做~j_0048.gif

本文出自 “Zimomo” 博客,请务必保留此出处http://zimomo.blog.51cto.com/10799874/1770149

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
<think>嗯,用户想用C++实现重建二叉树的方法,特别是根据前序和中序遍历来构建。我需要参考提供的引用内容,特别是引用[2]和[4]中的代码示例。首先,我应该确认递归方法的步骤:前序的第一个元素是根节点,然后在中序中找到根的位置,分割左右子树,再递归处理左右子树。用户可能需要详细的步骤解释和代码示例,同时注意边界条件,比如空数组的情况。还要考虑代码的效率,比如使用哈希表来快速查找中序中的根节点位置,如引用[1]提到的indexMap。不过引用[2]中的代码用的是循环查找,可能需要优化。另外,引用[4]提到了递归的模板,可以按照这个结构来组织代码。最后,需要生成相关问题,比如优化方法或应用场景。确保代码正确,语法正确,并符合用户的要求。</think>### C++实现重建二叉树的方法 根据前序遍历和中序遍历重建二叉树的步骤如下: 1. **递归终止条件** 当前序遍历或中序遍历序列为空时返回空指针。 2. **确定根节点** 前序遍历序列的第一个元素为当前子树的根节点值,例如:$pre[0] = rootVal$[^3]。 3. **划分左右子树** 在中序遍历序列中找到根节点的位置$i$,则: - 左子树的中序遍历范围:$vin[0]$至$vin[i-1]$ - 右子树的中序遍历范围:$vin[i+1]$至$vin[end]$ 前序遍历序列根据中序划分结果计算左右子树范围[^4]。 4. **递归构建子树** 对左右子树的序列递归调用构建函数。 #### 代码实现(优化版) ```cpp #include <vector> #include <unordered_map> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { public: unordered_map<int, int> indexMap; // 中序遍历值到索引的哈希表 TreeNode* buildTree(vector<int>& pre, int preStart, int preEnd, vector<int>& vin, int vinStart, int vinEnd) { if (preStart > preEnd || vinStart > vinEnd) return nullptr; int rootVal = pre[preStart]; TreeNode* root = new TreeNode(rootVal); int i = indexMap[rootVal]; // 直接通过哈希表查找位置 int leftSize = i - vinStart; root->left = buildTree(pre, preStart + 1, preStart + leftSize, vin, vinStart, i - 1); root->right = buildTree(pre, preStart + leftSize + 1, preEnd, vin, i + 1, vinEnd); return root; } TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { if (pre.empty() || vin.empty()) return nullptr; for (int i = 0; i < vin.size(); i++) indexMap[vin[i]] = i; // 预存中序遍历索引 return buildTree(pre, 0, pre.size()-1, vin, 0, vin.size()-1); } }; ``` #### 关键改进说明 1. **哈希表优化**:通过预存中序遍历索引,将查找根节点位置的时间复杂度从$O(n)$降为$O(1)$[^1]。 2. **避免向量拷贝**:原代码通过向量切片传递参数(如`leftpre`),现改为传递索引范围,减少内存占用。 3. **边界条件处理**:明确递归终止条件,避免栈溢出。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值