1935. 二叉樹重建(2)

                                   1935. 二叉樹重建
Description

對於二叉樹T,可以遞歸定義它的先序遍歷、中序遍歷和後序遍歷如下: PreOrder(T)=T的根節點+PreOrder(T的左子樹)+PreOrder(T的右子樹) InOrder(T)=InOrder(T的左子樹)+T的根節點+InOrder(T的右子樹) PostOrder(T)=PostOrder(T的左子樹)+PostOrder(T的右子樹)+T的根節點 其中加號表示字符串連接運算。例如,對下圖所示的二叉樹,先序遍歷爲DBACEGF,中序遍歷爲ABCDEFG。 
輸入一棵二叉樹的先序遍歷序列和中序遍歷序列,輸出它的廣度優先遍歷序列。 

Input

第一行爲一個整數t(0<t<10),表示測試用例個數。 以下t行,每行輸入一個測試用例,包含兩個字符序列s1和s2,其中s1爲一棵二叉樹的先序遍歷序列,s2爲中序遍歷序列。s1和s2之間用一個空格分隔。序列只包含大寫字母,並且每個字母最多隻會出現一次。 

Output

爲每個測試用例單獨一行輸出廣度優先遍歷序列。 

Sample Input
 Copy sample input to clipboard
2 
DBACEGF ABCDEFG 
BCAD CBAD 
Sample Output
DBEACGF 
BCAD


題目分析:

先序遍歷的第一個字符就是根,因此只需在中序遍歷中找到它,就知道左右子樹的先序和中序遍歷了。例如:
先序:D BACEGF    中序:ABCD EFG
由先序遍歷的第一個字符D 可知,此二叉樹的根節點爲D ,並且:
左子樹的先序遍歷爲:BAC    中序遍歷爲:ABC
右子樹的先序遍歷爲:EGF    中序遍歷爲:EFG
根據此規律,可通過遞歸來重構二叉樹,然後層序遍歷輸出。

#include<iostream>
#include<queue>
#include<string>
using namespace std;
string pre,mid;
int len,pos;
struct Node{
       Node *left;
       Node *right;
       char item;
       Node(char ch=0)
       {
            left=right=NULL;
            item=ch;
       }
}; 

void build(Node *&root,int begin,int end)
{
     if(begin>end||pos>=pre.size())  return ;//遞歸停止條件 
     
     root = new Node(pre[pos]);;
     int mpos=mid.find(pre[pos++]); //由前序遍歷的首字母可以在中序遍歷序列中查找對應位置,將中序的序列切開左子樹跟右子樹 
     
     build(root->left,begin,mpos-1);//遞歸構建 
     build(root->right,mpos+1,end);
}


int main()
{
    int time;
    cin>>time;
    while(time--)
    {
    cin>>pre>>mid;
    len=pre.size();
    pos=0;
    Node *root=new Node();
    build(root,0,len-1); //根據輸入的前序遍歷跟中序遍歷,構建一棵樹 
    
    queue<Node*>q;
    q.push(root);
    while(!q.empty()) //層序遍歷輸出 
    {
     Node *midd=q.front();
     q.pop();
     cout<<midd->item;
     if(midd->left)  q.push(midd->left);
     if(midd->right) q.push(midd->right);
     }
    cout<<endl;
    }
return 0;
}
    
    

(程序實現參考來自網絡)自己實現還是有問題,樹果然沒學好。o(︶︿︶)o唉






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章