中序遍历和先序遍历组合重建二叉树

问题描述:

       输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

分析:

       使用递归来实现这个问题

代码实现:

typedef struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
}TreeNode;

TreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder,int* endInorder)
{
	//先序遍历的第一个节点就是根节点
	int rootVal = startPreorder[0];
	TreeNode* root = new TreeNode();
	root->val = rootVal;
	root->left = root->right = NULL;

	if (startPreorder == endPreorder) //先序遍历只有一个节点,递归的出口
	{
		if (startInorder == endInorder  &&  *startPreorder == *startInorder) //中序遍历只有一个节点,且先序和中序相等
			return root;
		else
			throw std::exception("Invalid input.");
	}


	//在中序序列中找根节点
	int* rootInorder = startInorder;
	while (rootInorder <= endInorder && *rootInorder != rootVal)
		++rootInorder;

	if (rootInorder == endInorder && *rootInorder != rootVal) //在中序中找不到根节点,则输入数据错误
		throw std::exception("Invalid input.");



	//确定先序和中序中 左树和右树的区间
	int leftLength = rootInorder - startInorder; //中序中,左子树的长度
	int *leftPreorderEnd = startPreorder + leftLength; //先序中,左子树的结束为止

	if (leftLength > 0) //构建左子树(左子树还有节点)
		root->left = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1);
	if (leftLength < endPreorder - startPreorder) //构建右子树(右子树还有节点)
	{
		root->right = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);
	}

	return root;
}

TreeNode* Construct(int* preOrder, int* inOrder, int length)//构建
{
	if (preOrder == NULL || inOrder == NULL || length <= 0)
		return NULL;

	return ConstructCore(preOrder, preOrder + length - 1, inOrder, inOrder + length - 1);
}


int main()
{
	int preOrder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int inOrder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
	int len = sizeof(preOrder) / sizeof(preOrder[0]);
	TreeNode* root = Construct(preOrder, inOrder, len);
	return 0;
}

思考:

       1. 中序和后续结合重建?

       2. 字符串表示的中序和后续结合的重建

       3. 通过有2i+1 / 2i+2关系的数组进行重建

       4. 输入时便创建

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值