1. 程式人生 > >二叉樹求第三種遍歷序列

二叉樹求第三種遍歷序列

btree har dex logs 由於 bsp int tin 推理

// 樹的結點的結構:
struct TreeNode{
    TreeNode* LChild;
    TreeNode* RChild;
    char data;
};

註意: 求第三種序列必須有中序序列,比如前中求後 以及 中後求前,不可以前後求中

第一種情況:有前序序列和中序序列,求後序序列

前序: GDAFEMHZ  中序:ADEFGHMZ  需求得後序:AEFDHZMG

思路:利用遞歸解決.有一個函數

TreeNode* find_post_order(char* inOrder, char* preOrder, int length);

他的作用是: 在有一個中序和前序序列,以及這序列的長度(2者的長度當然一樣)前提下,求後序序列

以所給的序列為例子:(前序: GDAFEMHZ  中序:ADEFGHMZ)

  • 由於是前序,故而G必然是樹根
  • 以G分割中序序列知 ADEF G HMZ中,ADEF必為左子樹序列,HMZ必為右子樹序列
  • 遞歸對左子樹進行求解,對右子樹進行求解
  • :以G切割後:G DAFEMHZ 中序 ADEF HMZ
對於左子樹,中序序列起始指針無需改變,靠length控制長度即可
但是左子樹的前序序列需要 + 1,即去掉根結點
左子數的長度即是前序序列中根結點所在的index

對於右子樹,中序序列的指針位置是原本的中序序列指針起始位置+rootIndex + 1,即上面的註中的H的位置
至於前序序列,因為前序遍歷是 根->左->右, 所以右子樹的前序序列是原本前序序列的指針位置 + 1 + rootIndex 即躍過了根,再躍過左子書的前序部分
至於長度,其實就是中序序列中, length - (rootIndex + 1), 其中rootIndex + 1代表包括根節點以前的部分的長度(即註中ADEFG部分的長度

當對左右子樹都建立完,返回根節點指針即可
TreeNode* find_post_order(char* inOrder, char *preOrder, int length){
    if(length == 0) return NULL;

    
int rootIndex; for(rootIndex = 0; rootIndex < length; ++rootIndex){ if(inOrder[rootIndex] == *preOrder) break; }  // 求前序序列的第一個結點(即root結點)在中序序列中的坐標 TreeNode *rootNode = new TreeNode; rootNode->data = *preOrder; //LEFT SubTree 註意子樹中序, 前序的起始地點以及起到控制作用的序列長度 rootNode->LChild = find_post_order(inOrder, preOrder + 1, rootIndex); //RIGHT SubTree rootNode->RChild = find_post_order(inOrder + rootIndex + 1, preOrder + rootIndex + 1,length - (rootIndex + 1)); cout<<rootNode->data <<" "; //最終輸出 root結點 return rootNode; }

同理推理,根據中序和後序求取前序序列

可以假設中序為 ADEFGHMZ 後序為 AEFDHZMG 需求得後序為 GDAFEMHZ

以後序的最後一個元素(即根)切割中序序列結果為

中序 ADEF G HMZ

後序 AEFDHZM G

TreeNode* find_pre_order(char* inOrder, char* postOrder, int length){
    if(length == 0) return NULL;

    int rootIndex;
    for(rootIndex = 0; rootIndex < length; ++rootIndex){
        if(inOrder[rootIndex] == *(postOrder + length - 1))
            break;
    }

    TreeNode *rootNode = new TreeNode;
    rootNode->data = *(postOrder + length - 1);
    cout<<rootNode->data <<" ";
    rootNode->LChild = find_pre_order(inOrder, postOrder, rootIndex);
    rootNode->RChild = find_pre_order(inOrder + rootIndex + 1, postOrder + rootIndex, length - (rootIndex + 1));
    return rootNode;
}

二叉樹求第三種遍歷序列