[Jobdu] 題目1078:二叉樹遍歷


題目描述:

二叉樹的前序、中序、后序遍歷的定義:
前序遍歷:對任一子樹,先訪問跟,然后遍歷其左子樹,最后遍歷其右子樹;
中序遍歷:對任一子樹,先遍歷其左子樹,然后訪問根,最后遍歷其右子樹;
后序遍歷:對任一子樹,先遍歷其左子樹,然后遍歷其右子樹,最后訪問根。
給定一棵二叉樹的前序遍歷和中序遍歷,求其后序遍歷(提示:給定前序遍歷與中序遍歷能夠唯一確定后序遍歷)。

輸入:

兩個字符串,其長度n均小於等於26。
第一行為前序遍歷,第二行為中序遍歷。
二叉樹中的結點名稱以大寫字母表示:A,B,C....最多26個結點。

輸出:

輸入樣例可能有多組,對於每組測試樣例,
輸出一行,為后序遍歷的字符串。

樣例輸入:
ABC
BAC
FDXEAG
XDEFAG
樣例輸出:
BCA
XEDGAF

 

已知二叉樹的前序遍歷與中序遍歷,求后續遍歷。

前序遍歷方式為:根節點->左子樹->右子樹

中序遍歷方式為:左子樹->根節點->右子樹

后序遍歷方式為:左子樹->右子樹->根節點

從這里可以看出,前序遍歷的第一個值就是根節點,然后再中序遍歷中找到這個值,那么這個值的左邊部分即為當前二叉樹的左子樹部分前序遍歷結果,這個值的右邊部分即為當前二叉樹的右子樹部分前序遍歷結果。因此,通過這個分析,可以恢復這棵二叉樹,得到這樣的一段偽碼:

 

節點 getRoot(前序,中序)

c=前序第一個字符

pos=c在中序中的位置

len1=中序pos左半部分長度

len2=中序pos右半部分長度

新建節點r,令r的元素等於c

r的左兒子=getRoot(前序位置1開始的len1長度部分,中序pos位置的左半部分)

r的右兒子=getRoot(前序位置len1開始右半部分,中序pos位置的右半部分)

return r

 

#include <iostream>
using namespace std;

struct node{
    char v;
    node *left;
    node *right;
    node(char c){
        v = c;
        left = NULL;
        right = NULL;
    }
};

string A,B;

char genTree(node *t,string a,string b){
    int mid=1;
    string la,lb,ra,rb;
    if(a.length()>0){
        if(b.find(a[0])!=string::npos){
            mid = b.find(a[0]);
        }
        lb = b.substr(0,mid);
        rb = b.substr(mid+1,b.length());
        la = a.substr(1,lb.length());
        ra = a.substr(a.length()-rb.length(),a.length());
        t->left = new node(la[0]);
        genTree(t->left,la,lb);
        t->right = new node(ra[0]);
        genTree(t->right,ra,rb);
    }
}

void postOrder(node *t){
    if(t!=NULL){
        postOrder(t->left);
        postOrder(t->right);
        cout<<t->v;
    }
}

int main(int argc,char* argv[]){
    while(cin>>A>>B){
        node *root = new node(A[0]);
        genTree(root,A,B);
        postOrder(root);
        cout<<endl;
    }
    return 0;
}

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM