我们都知道二叉树有四种遍历结果,先序,中序,后序,层序;并且他们的遍历方式以及遍历结果我们也都知道 二叉树的非递归遍历.
所以: 在二叉树的先序遍历结果中,第一个数字总是树的根结点的值。但在中序遍历结果中,根结点位于序列的中间,左子树的结点值位于根结点的左边,右子树位于根结点的右边,因此,我们需要扫描中序遍历序列,才能找到根结点的值。
所以,我们已知的
先序遍历的结果是:{ 1, 2, 4, 3, 5, 6 };
中序遍历的结果是:{ 4, 2, 1, 5, 3, 6 };
我们已知的是先序遍历的第一个结点就是跟结点,所以在中序中就能找到跟结点,所以中序中根结点左边的就是左子树,同时可以在先序中找到右子树的根结点,这样递归的查找就能把每个结点的位置给找清楚了;
Node* _ReBulidTree(T* PreStart, T* PreEnd, T* MidStart, T* MidEnd)
{
Node* pRoot;
pRoot = new Node(*PreStart);
if (PreStart == PreEnd && MidStart == MidEnd)//如果只有一个pRoot结点就结束;
return pRoot;
T* pCur = MidStart;
while (pCur <= MidEnd && *pCur != *PreStart) //在中序中找到根结点
++pCur;
size_t lenth = pCur - MidStart; //左子树的长度;
T* LeftTreeEnd = PreStart + lenth; //左子树的尾结点
if (lenth > 0)//左子树存在的话,创建左子树
pRoot->_pLeft = _ReBulidTree(PreStart + 1, LeftTreeEnd, MidStart, pCur - 1); //左子树递归的创建
T* RightTreeStart = LeftTreeEnd + 1; //计算出右子树的根结点
if (PreEnd - PreStart > lenth) //如果右子树存在,递归的创建右子树
pRoot->_pRight = _ReBulidTree(RightTreeStart, PreEnd, pCur + 1, MidEnd);
return pRoot;
}
在这篇博客中,我只是把实现这个问题的关键代码上传了上去,完整的代码请看重建二叉树