我們都知道二叉樹有四種遍歷結果,先序,中序,後序,層序;並且他們的遍歷方式以及遍歷結果我們也都知道 二叉樹的非遞歸遍歷.
所以: 在二叉樹的先序遍歷結果中,第一個數字總是樹的根結點的值。但在中序遍歷結果中,根結點位於序列的中間,左子樹的結點值位於根結點的左邊,右子樹位於根結點的右邊,因此,我們需要掃描中序遍歷序列,才能找到根結點的值。
所以,我們已知的
先序遍歷的結果是:{ 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;
}
在這篇博客中,我只是把實現這個問題的關鍵代碼上傳了上去,完整的代碼請看重建二叉樹