二叉樹遍歷問題:前、中、后遍歷順序知二求一
二叉樹是每個結點(node)擁有子結點不超過兩個的樹。二叉樹的遍歷(Traversal)是指沿某條路線,依次對樹的每個結點做且僅做一次訪問的過程。其主要方式有前序遍歷(或稱先序遍歷)(Preorder Traversal)、中序遍歷(Inorder Traversal)、后序遍歷(Postorder Traversal)。前序遍歷指對每個結點,先訪問其根結點,再訪問其左側子結點,最后訪問其右側子結點;中序遍歷指對每個結點,先訪問其左側子結點,再訪問其根結點,最后訪問其右側子結點;后序遍歷指對每個結點,先訪問其左側子結點,再訪問其右側子結點,最后訪問其根結點。以下討論以D、L、R分別代指根結點、左側子結點、右側子結點。
根據二叉樹的兩種遍歷順序求第三種遍歷順序實際上是求樹的形態。對於一棵確定的二叉樹,其三種遍歷方式是唯一的。因此只要確定了樹的形態,就可以確定各種遍歷順序。二叉樹遍歷過程是一種遞歸過程。如對左側子結點的訪問,即為對左側子樹的遍歷。即二叉樹遍歷通式圖1-1所示。據此,可由三種遍歷方式的特點確定根結點,再不斷將剩余結點划分為左子樹與右子樹,並最終確定樹的形態,得到未知的遍歷順序。
下面以圖1-2中所示的一棵比較一般的簡單二叉樹為例,說明前、中、后遍歷順序知二求一的詳細過程。
1.由前序遍歷、中序遍歷求后序遍歷
由前序遍歷(DLR)的規則可知,首個訪問對象必為樹根(即首個根結點),后若干項為對左子樹的訪問,再后若干項直至最后是對右子樹的訪問。
例如:已知對某二叉樹前序遍歷順序為:ABDEGHCFI,中序遍歷順序為DBGEHACIF,求后序遍歷順序。
解:由前序遍歷順序可確定第一層根結點為A,記為D1=A。由中序遍歷順序可確定第一層的左子樹中序遍歷為L1=(DBGEH)in,右子樹中序遍歷為R1=(CIF)in。配合前序遍歷,可知第一層的左子樹前序遍歷為L1=(BDEGH)pre,右子樹前序遍歷為R1=(CFI)pre。再根據對L1中序、前序遍歷的結果,易知D2=B,同理可得各個結點左、右兩子樹的組成,再不斷迭代即可得到整個樹的結構。
由后序遍歷、中序遍歷求前序遍歷的過程與之類似。
2.由前序遍歷、后序遍歷求中序遍歷
由前序遍歷的規則,可知首個訪問對象必為樹根,第二個訪問對象必為樹根左子樹的樹根。同理,對於后序訪問,最后一個訪問對象為樹根,而倒數第二個訪問對象為右子樹的樹根。可據此將所有訪問對象不斷划分成各個左、右子樹,最終得到二叉樹結構。
例如:已知對某二叉樹前序遍歷順序為:ABDEGHCFI,后序遍歷順序為DGHEBIFCA,求中序訪問順序。
解:由前序遍歷順序可確定第一層根結點為A,記為D1=A;左子樹根結點為B,記為DL=B。由后序遍歷順序可確定第一層根結點為A;右子樹根結點為C,記為DR=C。依此可根據前序遍歷的順序得到對左、右子樹的前序遍歷順序,即L1=(BDEGH)pre,R1=(CFI)pre;可根據后序遍歷順序得到對左、右子樹后序遍歷順序,即L1=(DGHEB)post,R1=(IFC)post。再不斷迭代可得到整個樹的可能結構。
有一種特殊情況需要說明:當前序遍歷第二個訪問對象與后序遍歷倒數第二個訪問對象相同時,可認為是該結點左子樹樹根與右子樹樹根相同,也就是說該結點僅有一個子結點。在前序訪問和后序訪問中,此時這個子結點可以認為是該結點的左結點,也可認為是該結點的右結點,這不會影響它在前序訪問和后序訪問中被訪問的順序,但是會影響該結點在中序訪問中被訪問的順序。因此,若二叉樹中某結點僅有一個子結點時,不能由前序遍歷和后序遍歷得出中序遍歷的訪問順序。