所有代码均通过G++编译器测试,仅为练手纪录。
//面试题6:重建二叉树
//题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
// 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
//面试题6:重建二叉树
//题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
// 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
BinTreeNode* BinTreeBuildImpl(int *pBegPreOrder,int *pEndPreOrder,int *pBegInOrder,int *pEndInOrder)
{
//前序遍历序列的第一个元素,即为树的根结点
int nRootValue = pBegPreOrder[0];
BinTreeNode *pRootNode = new BinTreeNode(nRootValue);
//如果前序遍历序列结束,说明已经遍历完成
if(pBegPreOrder == pEndPreOrder)
{
if(pBegInOrder == pEndInOrder && *pBegPreOrder == *pBegInOrder)
{
return pRootNode;
}
else
{
LogError("input value error");
return NULL;
}
}
//查找中序遍历序列中的根结点
int *pRootInOrder = pBegInOrder;
while (pRootInOrder <= pEndInOrder && *pRootInOrder != nRootValue)
{
++pRootInOrder;
}
//如果未找到,说明输入序列有误
if(pRootInOrder == pEndInOrder && *pRootInOrder != nRootValue)
{
LogError("input value error");
return NULL;
}
//计算根结点在中序遍历序列中的位置
unsigned long nLeftSize = pRootInOrder - pBegInOrder;
//标记前序遍历序列中,左子树的结束位置(即中序遍历序列中根结点的位置)
int *pEndPreLeft = pBegPreOrder + nLeftSize;
//如果nLeftSize > 0,即中序遍历左边仍有元素,递归遍历左子树
if (nLeftSize > 0)
{
//创建左子树
pRootNode->m_pLeft = BinTreeBuildImpl(pBegPreOrder+1,pEndPreLeft, pBegInOrder, pRootInOrder-1);
}
//如果nLeftSize小于前序遍历序列的长度,即前序遍历右边仍有元素,递归遍历右子树
if (nLeftSize < (pEndPreOrder - pBegPreOrder) )
{
//创建右子树
pRootNode->m_pRight = BinTreeBuildImpl(pEndPreLeft+1, pEndPreOrder, pRootInOrder+1, pEndInOrder);
}
return pRootNode;
}
BinTreeNode* BinTreeBuild(int *pPreOrder,int *pInOrder,int nSize)
{
if(NULL == pPreOrder || NULL == pInOrder || 0 == nSize)
{
return NULL;
}
return BinTreeBuildImpl(pPreOrder,pPreOrder+nSize-1,pInOrder,pInOrder+nSize-1);
}
void TestBindTreeBuild()
{
int arrPreOrder[] = {1,2,4,7,3,5,6,8};
int arrInOrder[] = {4,7,2,1,5,3,8,6};
BinTreeNode* pRootNode = BinTreeBuild(arrPreOrder,arrInOrder,sizeof(arrPreOrder)/sizeof(int));
LogInfo("pRootNode:%p",pRootNode);
}
ZhaiPillary
2016-12-23