假設有棵樹,長下面這個樣子,它的前序遍歷,中序遍歷,後續遍歷都很容易知道。
preorder: gdafemhz
inorder: adefghmz
postorder: aefdhzmg
現在,假設僅僅知道前序和中序遍歷,如何求後序遍歷呢?比如,已知一棵樹的前序遍歷是」gdafemhz」,而中序遍歷是」adefghmz」應該如何求後續遍歷?
第一步,root最簡單,前序遍歷的第一節點g就是root。
第二步,繼續觀察前序遍歷gdafemhz,除了知道g是root,剩下的節點必然是root的左右子樹之外,沒法找到更多資訊了。
第三步,那就觀察中序遍歷adefghmz。其中root節點g左側的adef必然是root的左子樹,g右側的hmz必然是root的右子樹。
第四步,觀察左子樹adef,左子樹的中的根節點必然是大樹的root的leftchild。在前序遍歷中,大樹的root的leftchild位於root之後,所以左子樹的根節點為d。
第五步,同樣的道理,root的右子樹節點hmz中的根節點也可以通過前序遍歷求得。在前序遍歷中,一定是先把root和root的所有左子樹節點遍歷完之後才會遍歷右子樹,並且遍歷的右子樹的第乙個節點就是右子樹的根節點。
如何知道**是前序遍歷中的左子樹和右子樹的分界線呢?通過中序遍歷去數節點的個數。
在上一次中序遍歷中,root左側是a、d、e、f,所以有4個節點位於root左側。那麼在前序遍歷中,必然是第1個是g,第2到第5個由a、d、e、f過程,第6個就是root的右子樹的根節點了,是m。
第六步,觀察發現,上面的過程是遞迴的。先找到當前樹的根節點,然後劃分為左子樹,右子樹,然後進入左子樹重複上面的過程,然後進入右子樹重複上面的過程。最後就可以還原一棵樹了。
第七步,其實,如果僅僅要求寫後續遍歷,甚至不要專門占用空間儲存還原後的樹。只需要稍微改動第六步,就能實現要求。僅需要把第六步的遞迴的過程改動為如下:
1 確定根,確定左子樹,確定右子樹。
2 在左子樹中遞迴。
3 在右子樹中遞迴。
// size是這棵樹的節點個數
bintree* createbintree(char* pre,char* inorder,int size)
int main()
其實上面的**寫得不夠簡潔。題目只要求輸出後續遍歷,並沒有要求建樹。所以,不需要去計算出node->left與node->right,也不需要去return node。改進版本如下
struct treenode
;void binarytreefromorderings(char* inorder, char* preorder, int length)
;void binarytreefromorderings(char* inorder, char* preorder, int length)
{ if(length == 0)
{//cout<
二叉樹的前序遍歷 中序遍歷和後序遍歷
include includeusing namespace std typedef struct bitnodebitnode,bitree void initbitree bitree t 構造空二叉樹 void createbitree bitree t 生成二叉樹 void preorder...
二叉樹的遍歷 前序遍歷 中序遍歷 後序遍歷
二叉樹的遍歷分為前序遍歷 中序遍歷 後序遍歷 前序遍歷是指,對於樹中的任意節點來說,先列印這個節點,然後再列印它的左子樹,最後列印它的右子樹。中序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列印它本身,最後列印它的右子樹。後序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列...
二叉樹的前序遍歷 中序遍歷 後序遍歷
二叉樹分為根節點 左子節點 右子節點,如下圖所示,前序遍歷的順序是 根左右 即 abc,中序遍歷的順序是 左根右 即 bac,後續遍歷的順序是 左右根 即 bca,給定乙個二叉樹,求三種遍歷方式的結果,以下圖為例 前序遍歷 根左右 a b d e f g c h k 中序遍歷 左根右 d b f e...