1. 程式人生 > 其它 >已知二叉樹的兩種遍歷,求另一個遍歷

已知二叉樹的兩種遍歷,求另一個遍歷

第一種:已知前序遍歷、中序遍歷求後序遍歷
前序遍歷:ABCDEF
中序遍歷:CBDAEF
在進行分析前讀者需要知道不同遍歷結果的特點
1、前序遍歷的第一元素是整個二叉樹的根節點
2、中序遍歷中根節點的左邊的元素是左子樹,根節點右邊的元素是右子樹
3、後序遍歷的最後一個元素是整個二叉樹的根節點
(如果讀者不明白上述三個特點,建議再回去看一下三種不同遍歷對應的程式碼,並在紙上寫出一個簡單的二叉樹的三種不同的遍歷結果,以加深對三種不同遍歷的理解)
用上面這些特點來分析遍歷結果,

第一步:先看前序遍歷A肯定是根節點
第二步:確認了根節點,再來看中序遍歷,中序遍歷中根節點A的左邊是CBD,右邊是EF,所有可以確定二叉樹既有左子樹又有右子樹

第三步:先來分析左子樹CBD,那麼CBD誰來做A的左子樹呢?這個時候不能直接用中序遍歷的特點(左->根->右)得出左子樹應該是這個樣子

因為有兩種情況都滿足中序遍歷為CBD

無法直接根據中序遍歷來直接得出左子樹的結構,這個時候就要返回到前序遍歷中去
觀察前序遍歷ABCDEF,左子樹CBD在前序遍歷中的順序是BCD,意味著B是左子樹的根節點(這麼說可能不太好理解,換個說法就是B是A的左子樹),得出這個結果是因為如果一個二叉樹的根節點有左子樹,那麼
這個左子樹一定在前序遍歷中一定緊跟著根節點(這個是用前序遍歷的特點(根->左->右)得出的),到這裡就可以確認B是左子樹的根節點

第四步:再觀察中序遍歷CBDAEF,B元素左邊是C右邊是D,說明B節點既有左子樹又有右子樹,左右子樹只有一個元素就可以直接確定了,不用再返回去觀察前序遍歷

第五步:到這裡左子樹的重建就已經完成了,現在重建右子樹,因為重建右子樹的過程和左子樹的過程一模一樣,步驟就不像上面寫這麼細了,觀察中序遍歷右子樹為EF,再觀察前序遍歷ABCDEF中右子樹
的順序為EF,所以E為A的右子樹,再觀察中序便利中E只有右邊有F,所有F為E的右子樹,最後得到的二叉樹是這個樣子的

所有求得的後序遍歷為:CDBFEA
總結一下上述步驟: 先觀察前序遍歷找到根節點->觀察中序遍歷將根節點左邊歸為左子樹元素,右邊歸為右子樹元素(可能會出現只有左子樹或者右子樹的情況)->觀察前序遍歷中左\右子樹幾個元素的順序,最靠前的為左\右子樹的根節點->重複前面的步驟
第二種:已知中序遍歷、後序遍歷求前序遍歷(題還是上面這道)


中序遍歷:CBDAEF
後序遍歷為:CDBFEA
仍然是根據不同遍歷方式結果的特點來重構二叉樹,過程很相似這裡就不詳細說了,後序遍歷的最後一個元素A是根節點,在中序遍歷中以根節點A作為分界將元素分為左子樹(CBD)和右子樹(EF),再觀察後序遍歷中左子樹的順序是CDB,可以判斷出B是左子樹的根節點(因為後序遍歷是:左->右->根),再觀察中序遍歷,B元素左邊是C右邊是D,說明B節點既有左子樹又有右子樹,左右子樹只有一個元素就可以直接確定了,不用再返回去觀察後序遍歷,左子樹重建完成,
現在來看右子樹,右子樹有兩個元素EF,觀察後序遍歷E在F的後面,所以E是右子樹的根節點,然後看中序遍歷中E只有右邊一個F元素了,即F是E的右子樹,此時整個二叉樹重構完成
總結一下上述步驟:先觀察後序遍歷找到根節點->觀察中序遍歷將根節點左邊歸為左子樹元素,右邊歸為右子樹元素(可能會出現只有左子樹或者右子樹的情況)->觀察後序遍歷中左\右子樹幾個元素的順序,最靠後的為左\右子樹的根節點->重複前面的步驟
注意:已知前序遍歷、後序遍歷無法求出中序遍歷(因為由前序後序重構出來的二叉樹不止一種)
舉個例子

左圖這兩種二叉樹前序(BEFA)和後序(AFEB)一樣,但對應的中序遍歷結果不一樣(左邊的是AFEB右邊的是BEFA),所以僅靠前序後序是不能重構出唯一的二叉樹。