重建二叉树

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

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

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

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

**项目概述:** 本资源提供了一套采用Vue.js与JavaScript技术栈构建的古籍文献文字检测与识别系统的完整源代码及相关项目文档。当前系统版本为`v4.0+`,基于`vue-cli`脚手架工具开发。 **环境配置与运行指引:** 1. **获取项目文件**后,进入项目主目录。 2. 执行依赖安装命令: ```bash npm install ``` 若网络环境导致安装缓慢,可通过指定镜像源加速: ```bash npm install --registry=https://registry.npm.taobao.org ``` 3. 启动本地开发服务器: ```bash npm run dev ``` 启动后,可在浏览器中查看运行效果。 **构建与部署:** - 生成测试环境产物: ```bash npm run build:stage ``` - 生成生产环境优化版本: ```bash npm run build:prod ``` **辅助操作命令:** - 预览构建后效果: ```bash npm run preview ``` - 结合资源分析报告预览: ```bash npm run preview -- --report ``` - 代码质量检查与自动修复: ```bash npm run lint npm run lint -- --fix ``` **适用说明:** 本系统代码经过完整功能验证,运行稳定可靠。适用于计算机科学、人工智能、电子信息工程等相关专业的高校师生、研究人员及开发人员,可用于学术研究、课程实践、毕业设计或项目原型开发。使用者可在现有基础上进行功能扩展或定制修改,以满足特定应用场景需求。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
【EI复现】基于阶梯碳交易的含P2G-CCS耦合和燃气掺氢的虚拟电厂优化调度(Matlab代码实现)内容概要:本文介绍了基于阶梯碳交易机制的虚拟电厂优化调度模型,重点研究了包含P2G-CCS(电转气-碳捕集与封存)耦合技术和燃气掺氢技术的综合能源系统在Matlab平台上的仿真与代码实现。该模型充分考虑碳排放约束与阶梯式碳交易成本,通过优化虚拟电厂内部多种能源设备的协同运行,提升能源利用效率并降低碳排放。文中详细阐述了系统架构、数学建模、目标函数构建(涵盖经济性与环保性)、约束条件处理及求解方法,并依托YALMIP工具包调用求解器进行实例验证,实现了科研级复现。此外,文档附带网盘资源链接,提供完整代码与相关资料支持进一步学习与拓展。; 适合人群:具备一定电力系统、优化理论及Matlab编程基础的研究生、科研人员或从事综合能源系统、低碳调度方向的工程技术人员;熟悉YALMIP和常用优化算法者更佳。; 使用场景及目标:①学习和复现EI级别关于虚拟电厂低碳优化调度的学术论文;②掌握P2G-CCS、燃气掺氢等新型低碳技术在电力系统中的建模与应用;③理解阶梯碳交易机制对调度决策的影响;④实践基于Matlab/YALMIP的混合整数线性规划或非线性规划问题建模与求解流程。; 阅读建议:建议结合提供的网盘资源,先通读文档理解整体思路,再逐步调试代码,重点关注模型构建与代码实现之间的映射关系;可尝试修改参数、结构或引入新的约束条件以深化理解并拓展应用场景。
<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. **边界条件处理**:明确递归终止条件,避免栈溢出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值