《剑指Offer》面试题7:重建二叉树

要求:重建二叉树

       输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。二叉树节点的定义如下:

struct BinaryTreeNode
{
	int              m_nValue;
	BinaryTreeNode	*m_pLeft;
	BinaryTreeNode	*m_pRight;
};

测试用例:

  1. 普通二叉树(完全二叉树;不完全二叉树)
  2. 特殊二叉树(所有节点都没有右子节点的二叉树;所有节点都没有左子节点的二叉树;只有一个节点的二叉树)
  3. 特殊输入测试(二叉树的根节点指针为nullptr;输入的前序遍历序列和中序遍历序列不匹配)

本题考点:

  1. 考查对二叉树的前序遍历和中序遍历的理解程度。只有对二叉树的不同遍历算法有了深刻的理解,应聘者才有可能在遍历序列中划分出左右字数对应的子序列。
  2. 考查分析复杂问题的能力。我们把构建二叉树的大问题分解成构建左右子树的两个小问题。我们发现小问题和大问题在本质上是一致的,因此可以用递归的方法解决。

源代码:

BinaryTreeNode *ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder)
{
	//前序遍历序列的第一个数字是根节点的值
	int rootValue = startPreorder[0];

	BinaryTreeNode *root = new BinaryTreeNode();
	root->m_nValue = rootValue;
	root->m_pLeft = root->m_pRight = nullptr;

	if (startPreorder == endPreorder)
	{
		if (startInorder == endInorder && *startPreorder == *startInorder)
			return root;
		else
			throw exception("Invalid input");
	}

	//在中序遍历中找到根节点的值
	int *rootInorder = startInorder;
	while (rootInorder <= endInorder && *rootInorder != rootValue)
		++rootInorder;

	if (rootInorder == endInorder && *rootInorder != rootValue)
		throw exception("Invalid input");

	int leftLength = rootInorder - startInorder;
	int *leftPreorderEnd = startPreorder + leftLength;
	if (leftLength > 0)
	{
		//构建左子树
		root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1);
	}

	if (leftLength < endPreorder - startPreorder)
	{
		//构建右子树
		root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);
	}

	return root;
}

参考代码:https://github.com/zhedahht/CodingInterviewChinese2/tree/master/07_ConstructBinaryTree
自己代码:https://github.com/quinta2019/Offer/tree/master/07_Q_ConstructBinaryTree

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值