根據 中序遍歷 和 後序遍歷構造樹(Presentation)(C++)

  好不容易又到週五了,週末終於能夠休息休息了。寫這一篇隨筆只是心血來潮,下午問了一位朋友PAT考的如何,順便看一下他考的試題,裏面有最後一道題,是關於給出中序遍歷和後序遍歷而後求一個層次遍歷。等等,我找一下連接出來......node

  1127. ZigZagging on a Tree (30):https://www.patest.cn/contests/pat-a-practise/1127算法

  忽然想起之前學數據結構的時候若是給出一箇中序遍歷和一個後序遍歷而後讓你畫出樹的結構或求出先序遍歷之類的題目,若是用筆來畫,三下五除二可以一會兒就畫出來,但關於用語言編寫出來卻歷來沒有想過,真是慚愧,因此這篇隨筆的內容思惟可能比較簡單低階,請你們包涵。數據結構

  因此想試一下能不能寫一寫,加之最近在補習一些算法和數據結構之類的題目,能夠做爲一個練手的題目。想不到要動手以前理清一下構造的過程,最後卻有些明朗的感受,這也是我想寫下這篇隨筆的緣由,雖然簡單,但頗有意義。好,說了這麼多廢話...下面開始:post

  對於一棵樹的中序遍歷,根節點確定處於遍歷結果的中間(假設這棵樹有左子樹),後序遍歷的時候根節點確定是最後一個遍歷的元素。因此能夠輕易獲得根在中序遍歷中的位置,根據中序遍歷的性質,以根爲中點日後遍歷到的元素就是這棵樹的右子樹元素,往前遍歷到的就是這棵樹的左子樹元素。然後續遍歷也是把這棵樹的左子樹所有遍歷完整以後再來遍歷右子樹,所以在後續遍歷中,左子樹和右子樹的元素也是有明顯的界限。而對於根節點的左節點和右節點也是一樣的道理。舉個例子spa

                  

因此咱們從最初的遍歷順序開始,找出後續遍歷的最後一個元素在中序遍歷中的位置,而後以這個位置爲重點,往右的遍歷元素爲A,往左的遍歷元素爲B,根據A和B的長度能夠肯定在後續遍歷中的遍歷元素邊界,對A和B進行上一步的操做,直到全部元素遍歷完成。代碼:code

Node *getRoot(int* inorder,int* postorder,int ix,int iy,int px,int py){
    Node *node = new Node(postorder[py]);
    int p = findElem(inorder,postorder[py],ix,iy);
    if(-1 != p){
        int lix,liy,lpx,lpy,rix,riy,rpx,rpy;
        if(p == iy)node->right = NULL;
        else{
            rix = p+1;
            riy= iy;
            rpy = py-1;
            rpx = rpy - (riy-rix);
            node->right = getRoot(inorder,postorder,rix,riy,rpx,rpy);
        }
        if(p == ix) node->left = NULL;
        else{
            lix = ix;
            liy = p -1;
            lpx = px;
            lpy = px + (liy-lix);
            node->left = getRoot(inorder,postorder,lix,liy,lpx,lpy);
        }

        return node;
    }else
    return NULL;
}
void MidTraverse(Node *root){
    if(NULL != root){
        cout<<root->val<<" ";
        MidTraverse(root->left);
        MidTraverse(root->right);
    }
}
int main(){
    int count;
    cin>>count;
    int *inorder = new int[count];
    int *postorder = new int[count];
    for(int i =0;i<2;i++){
        for(int j=0;j<count;j++){
            int in;
            cin>>in;
            if(0==i) inorder[j] = in;
            else postorder[j] = in;
        }
    }
    Node *root = getRoot(inorder,postorder,0,count-1,0,count-1);
    if(NULL !=root)
        MidTraverse(root);
}

節點定義爲:blog

typedef struct _Node{
    int val;
    struct _Node *left,*right;
    _Node(int _val):val(_val),left(NULL),right(NULL){}
}Node;

運行代碼,最後結果在乎料以內:ci

 

 

 

        深圳的工做壓力強行把市民的生活節奏拉的飛快,上了一週的班心緒有些煩躁,下班出了公司的門卻意外地迎來了樹葉和泥土的味道,是一場雨清澈了整片空氣。get

相關文章
相關標籤/搜索