每日一题之由前序遍历和中序遍历重建二叉树

前序遍历和中序遍历的重建二叉树:

首先构建二叉树的节点:

struct TreeNode
{
	int _value;
	TreeNode* _left;
	TreeNode* _right;
};
分析:

在二叉树的前序遍历中,第一个数字总是树的根节点的值,但在中序遍历的序列中,根节点的值在序列的中间,左子输的节点位于根节点的左侧,右子树的节点位于根节点的右侧。所以我们需要扫描一遍中序遍历才能知道它的根节点的值。

我们来分析如图所示的二叉树:


前序遍历的第一个节点1就是它的根节点。扫描中序遍历的序列,就能确定根节点的值。根据中序遍历的特点,在根结点的值1前面的3个数字都是左子树根节点的值,1右边的数字都是右子数节点的值。

由于在中序遍历序列中,有三个数是左子树节点的值,因此左子树有三个左子树的节点。同样在前序遍历的序列中,根据节点后面的三个数字就是三个左子树节点的值,再后面的所有数字都是右子树节点的值。这样我们就可以根据前序遍历和中序遍历分别找到左右子树对应的子序列。如图所示:


实现代码:

struct TreeNode
	{
		int _value;
		TreeNode* _left;
		TreeNode* _right;
	};
TreeNode* Construct(int* prevorder, int* inorder, int* length)
{
	if (prevorder == NULL || inorder == NULL || length < 0)
		return NULL;
	return ConstructCore(prevorder, prevorder + length - 1, inorder, inorder + lenghth - 1);
}
TreeNode* ConstructCore
{
	int* startprevorder,int* endprevorder,
	int* startinorder,int* endinorder
}
int  rootvalue = startprevorder[0];
TreeNode* root = new TreeNode();
root->_value = rootvalue;
root->_left = root->_right = NULL;
if (startpreorder == endprevorder)
{
	if (startinorder == endinorder&&*startprevorder == *startinorder)
		return root;
	else
		throw std::exception("Invalid input");
}
int* rootinorder = startinorder;
while (rootinorder <= endinorder&&*rootinorder != rootvalue)
{
	++rootinorder;
}
if (rootinorder == endinorder&&*rootinorder != rootvalue)
{
	throw std::exception("Invalid input");
}
int leftlength = rootinorder - startinorder;
int*leftpreorderend = startprevorder + leftlength;
if (leftlength > 0)
{
	root->_left = ConstructCore(startprevorder + 1, leftpreorderend, startinorder, rootinorder - 1);
}
if (leftlength < endpreorder - startpreorder)
{
	root->_right = ConstructCore(leftpreorderend + 1, endpreorder, rootinorder + 1, endinorder);
}
return root;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值