L2-006 樹的遍歷 (25 分)
給定一棵二叉樹的后序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這里假設鍵值都是互不相等的正整數。
輸入格式:
輸入第一行給出一個正整數N(≤),是二叉樹中結點的個數。第二行給出其后序遍歷序列。第三行給出其中序遍歷序列。數字間以空格分隔。
輸出格式:
在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多余空格。
輸入樣例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
輸出樣例:
4 1 6 3 5 7 2
二叉樹:
前(先)序遍歷:根左右
中序遍歷:左根右
后序遍歷:左右根(最后一個為根節點)
層序遍歷:BFS從上到下,從左到右
前三個可以通過遞歸實現,最后一個BFS。
傳送門:
代碼:
1 //L2-006 樹的遍歷-二叉樹的后序遍歷、中序遍歷、層序遍歷 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e5+10; 6 7 struct node{ 8 int l,r; 9 }tree[maxn]; 10 11 int beh[maxn],mid[maxn]; 12 13 int build(int la,int ra,int lb,int rb)//la,ra為中序遍歷的, lb,rb為后序遍歷的 14 { 15 if(la>ra) return 0; 16 int rt=beh[rb];//根節點為后序遍歷的最后一個 17 int p1=la; 18 while(mid[p1]!=rt) p1++;//找到根節點的位置下標 19 int p2=p1-la; 20 tree[rt].l=build(la,p1-1,lb,lb+p2-1);//遞歸建左子樹 21 tree[rt].r=build(p1+1,ra,lb+p2,rb-1);//遞歸建右子樹 22 // cout<<rt<<endl; 23 return rt;//返回值為結束的根節點值 24 } 25 26 void bfs(int x)//bfs求得層序遍歷 27 { 28 vector<int> vec; 29 queue<int> que; 30 que.push(x); 31 while(!que.empty()){ 32 int ret=que.front(); 33 que.pop(); 34 if(ret==0) break; 35 vec.push_back(ret); 36 if(tree[ret].l!=0){//左子樹不為空 37 que.push(tree[ret].l); 38 } 39 if(tree[ret].r!=0){//右子樹不為空 40 que.push(tree[ret].r); 41 } 42 } 43 int l=vec.size(); 44 for(int i=0;i<l-1;i++) 45 cout<<vec[i]<<" "; 46 cout<<vec[l-1]<<endl; 47 } 48 49 int main() 50 { 51 int n; 52 cin>>n; 53 for(int i=1;i<=n;i++) 54 cin>>beh[i]; 55 for(int i=1;i<=n;i++) 56 cin>>mid[i]; 57 build(1,n,1,n);//建樹 58 bfs(beh[n]); 59 }