题目:
输入某二叉树的前序遍历和中序遍历的结构,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序便利序列{1, 2, 4, 7, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 8, 3, 6},则重建出图2.6所示的二叉树并输出它的头结点。二叉树的定义如下:
struct BinaryTreeNoe
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode*
}
实现代码:
BinaryTreeNode* ConstructCore(int* pPreOrderBegin, int* pPreOrderEnd, int* pInOrderBegin, int* pInOrderEnd)
{
int rootValue = pPreOrderBegin[0]; // 前序遍历序列中第一个元素是根节点
BinaryTreeNode* pRoot = new BinaryTreeNode;
pRoot->m_nValue = rootValue;
pRoot->m_pLeft = pRoot->m_pRight = nullptr;
if (pPreOrderBegin == pPreOrderEnd)
{
if ((pInOrderBegin == pInOrderEnd) && (*pPreOrderBegin == *pInOrderBegin)) return pRoot; // 只有一个节点了
else return nullptr; // 数据有问题
}
int* pInOrderRoot = pInOrderBegin; // 中序遍历序列中的根节点
for (; pInOrderRoot != pInOrderEnd; ++pInOrderRoot)
{
if (*pInOrderRoot == rootValue) break;
}
if (pInOrderRoot == pInOrderEnd && (*pInOrderRoot != rootValue)) // 判断在中序遍历序列中是否找到了根节点
return nullptr;
int leftSubTreeSize = pInOrderRoot - pInOrderBegin; // 左子树长度
int* pPreOrderLeftEnd = pPreOrderBegin + leftSubTreeSize; // 前序遍历序列中左子树最后一个数据
int rightSubTreeSize = pInOrderEnd - pInOrderRoot; // 右子树长度
if (leftSubTreeSize > 0) // 有左子树,创建左子树
pRoot->m_pLeft = ConstructCore(pPreOrderBegin + 1, pPreOrderLeftEnd, pInOrderBegin, pInOrderRoot - 1);
if (rightSubTreeSize > 0) // 有右子树,创建右子树
pRoot->m_pRight = ConstructCore(pPreOrderLeftEnd + 1, pPreOrderEnd, pInOrderRoot + 1, pInOrderEnd);
return pRoot;
}
BinaryTreeNode* Construct(int* pPreOrderBegin, int* pInOrderBegin, int size)
{
if (nullptr == pPreOrderBegin || nullptr == pInOrderBegin || size <= 0) return nullptr;
return ConstructCore(pPreOrderBegin, pPreOrderBegin + size - 1, pInOrderBegin, pInOrderBegin + size - 1);
}