L2-006. 树的遍历(利用后序中序还原二叉树)

来源:互联网 发布:易企秀一样的软件 编辑:程序博客网 时间:2024/05/16 14:38

题目链接:https://www.patest.cn/contests/gplt/L2-006

思路分析:后序可以知道树根,然后在中序中找出树根,又可以确定左右子树,然后递归地对左右子树进行分解,即可还原出二叉树。最后把建好的树BFS一遍就可以写出层次遍历了。

AC代码如下:

[cpp] view plain copy
print?
  1. #include<iostream>  
  2. #include<vector>  
  3. #include<queue>  
  4. #include<cstring>  
  5. #include<cstdio>  
  6. using namespace std;  
  7. const int maxn=3005;  
  8. int tree[maxn];  
  9. void build(int rt,vector<int>a,vector<int>b)//递归建树  
  10. {  
  11.     if(a.size()==0) return ;//递归出口  
  12.     int p=0;  
  13.     for(int i=0;i<b.size();i++)//找出根  
  14.         if(b[i]==a[a.size()-1]) p=i;  
  15.     vector<int>al,ar,bl,br;  
  16.     for(int i=0;i<p;i++) al.push_back(a[i]);//左子树的后序遍历序列  
  17.     for(int i=p;i<a.size()-1;i++) ar.push_back(a[i]);//右子树的后序遍历序列  
  18.     for(int i=0;i<p;i++) bl.push_back(b[i]);//左子树的中序遍历序列  
  19.     for(int i=p+1;i<b.size();i++) br.push_back(b[i]);//右子树的中序遍历序列  
  20.     tree[rt]=b[p];//建根  
  21.     build(rt<<1,al,bl);//递归建左子树  
  22.     build(rt<<1|1,ar,br);//递归建右子树  
  23. }  
  24. void bfs()//用bfs层次遍历  
  25. {  
  26.     queue<int>q;  
  27.     int root=1;  
  28.     q.push(root);  
  29.     int f=0;  
  30.     while(q.size())  
  31.     {  
  32.         if(f++) cout<<" ";  
  33.         root=q.front();  
  34.         cout<<tree[root];  
  35.         q.pop();  
  36.         if(tree[root<<1]!=-1) q.push(root<<1);  
  37.         if(tree[root<<1|1]!=-1) q.push(root<<1|1);  
  38.     }  
  39.     cout<<endl;  
  40. }  
  41. int main()  
  42. {  
  43.     //freopen("in.txt","r",stdin);  
  44.     int n,x;  
  45.     while(cin>>n)  
  46.     {  
  47.         memset(tree,-1,sizeof(tree));  
  48.         vector<int>a,b;  
  49.         for(int i=0;i<n;i++) cin>>x,a.push_back(x);  
  50.         for(int i=0;i<n;i++) cin>>x,b.push_back(x);  
  51.         build(1,a,b);  
  52.         bfs();  
  53.     }  
  54.     return 0;  
  55. }