首先了解什麼是二叉樹重建:
我們知道, 二叉樹的遍歷有三種, 前序, 中序, 後序.
我們可以根據其中的任意兩種遍歷得到的序列, 求出這顆二叉樹另一種遍歷序列~
如給出前序與中序
前:4231756
中:3214576
求其後序遍歷(3125674)
思路: 前序遍歷中的第乙個字元, 毫無疑問肯定是根結點! (在上面給出的前序中, 第乙個字元是4)
根據而在中序中, 該根結點是乙個分水嶺, 它將中序序列變成了兩半, 左一半是根結點的左兒子部分(321), 右一半是右兒子部分(576)
由於要求的是後序序列, 我們得到的根節點, 事實上是要放在最後的, 我們可以用乙個ans陣列儲存(稍後體會)
接著, 我們要對第乙個根結點4的左兒子部分進行剖析, 把左兒子部分也建成樹, 同理, 稍後把右兒子部分建成樹~(遞迴!)
理解了上面的思路後, 看看**實現的過程
#include#include//n表示待查序列長度, s1是前序序列, s2是中序序列, s是ans陣列的指標
void build(int n, char *s1, char *s2, char *s)
int main()
return 0;
}
再看看由中序和後序求前序:
資料還是原先的資料:
中:3214576
後:3125674
求其前序遍歷(4231756)
思路轉化一下,可以先由後序的最後乙個字元可知根結點.
注意點:
不同與前面由前序中序的重建, 所求後序的儲存順序是 左子樹 -> 右子樹 -> 根
因此, 在上面求後序的時候, 是在把左子樹和右子樹都遞迴好了後, 再最後把根放在答案陣列的最後面
而在根據中序和後續求前序的過程中, 我們前序的儲存順序是 根 -> 左子樹 -> 右子數
所以, 我們一開始求得根結點後就要儲存下來, 再去遞迴左右子樹!
看**理解:
#include#includeint pos;
void build(int n, char *s1, char *s2, char *s)
int main()
return 0;
}
看完以上兩個示例, 不知道你們有沒有找出點規律的蛛絲馬跡, 看不懂的話仔細的揣摩兩遍, 就懂了
這裡有些很有規律的東西, 記下後可以當初乙個偽模板
求後序時, 遞迴函式的順序是, 遞迴左子樹 -> 遞迴右子樹 -> 儲存根 (和後序的結構一樣, 是左-右-根)
求前序時, 遞迴函式的順序是, 儲存根 -> 遞迴左子樹 -> 遞迴右子樹 (同理, 和前序的結構一樣)
不難, 最後還有根據前序、後續求中序的**, 但是這兩種順序求出的樹是不唯一的, 但是也能敲~
二叉樹 重建二叉樹
問題 給定二叉樹的前序遍歷結果和中序遍歷結果,恢復出原二叉樹。假設二叉樹中的元素都不重複,給定二叉樹的前序遍歷序列,二叉樹的中序遍歷序列。看到此題,我首先想到的是尋找根節點,由前序遍歷序列可以看出根節點為1,此時通過中序遍歷可以看出來4,7,2在根節點的左子樹,5,3,8,6在樹的右節點。此時我們可...
二叉樹 重建二叉樹
題目給定兩個陣列,乙個是前序遍歷陣列 preorder 乙個是中序遍歷陣列 inorder 要求輸出還原二叉樹 核心在於我們要理解前序和中序便利的特點 前序遍歷 根節點 左節點 右節點 中序遍歷 左節點 根節點 右節點 所以我們從二叉樹的根節點開始重構 也就是preorder的第乙個值 同時用乙個m...
二叉樹重建
摘自劉汝佳的 演算法競賽入門經典 preorder t t 的根結點 preorder t 的左子樹 preorder t 的右子樹 inorder t inorder t 的左子樹 t 的根結點 inorder t 的右子樹 postorder t postorder t 的左子樹 postord...