1020 Tree Traversals (25分)

数据结构里的经典题了,不过这次是借助(STL)而不是花哨的指针 ^_^

用一个(pair)数组来存树,结点上存的是下标,最后输出结果时要将下标对应成值,恰好我们存了中序遍历的下标和值的对应关系,于是最后输出层序遍历结果时将下标转成对应中序序列中的值就好了。

ps:树中每个结点的值都是不同的。

const int N=35;
PII tree[N];
unordered_map<int,int> pos;
int post[N];
int in[N];
int level[N],cnt;
int n;

int build(int inl,int inr,int postl,int postr)
{
    if(inl>inr) return -1;
    
    int root=post[postr];
    int k=pos[root];
    
    int lchild=build(inl,k-1,postl,postl+k-inl-1);
    int rchild=build(k+1,inr,postl+k-inl,postr-1);
    tree[k]={lchild,rchild};
    return k;
}

void bfs(int root)
{
    queue<int> q;
    q.push(root);
    
    while(q.size())
    {
        int t=q.front();
        q.pop();
        
        level[cnt++]=t;
        
        if(~tree[t].fi) q.push(tree[t].fi);
        if(~tree[t].se) q.push(tree[t].se);
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n;i++) cin>>post[i];
    for(int i=0;i<n;i++) cin>>in[i],pos[in[i]]=i;

    int root=build(0,n-1,0,n-1);
    bfs(root);
    
    for(int i=0;i<cnt;i++)
    {
        if(i) cout<<' '<<in[level[i]];
        else cout<<in[level[i]];
    }

    //system("pause");
    return 0;
}

而如果用(map)存值,则结点直接存的值。
ps:如果结点的值由重复,则不能采用这种写法。

const int N=35;
unordered_map<int,PII> tree;
unordered_map<int,int> pos;
int post[N];
int in[N];
int level[N],cnt;
int n;

int build(int inl,int inr,int postl,int postr)
{
    if(inl>inr) return -1;
    
    int root=post[postr];
    int k=pos[root];
    
    int lchild=build(inl,k-1,postl,postl+k-inl-1);
    int rchild=build(k+1,inr,postl+k-inl,postr-1);
    tree[root]={lchild,rchild};
    return root;
}

void bfs(int root)
{
    queue<int> q;
    q.push(root);
    
    while(q.size())
    {
        int t=q.front();
        q.pop();
        
        level[cnt++]=t;
        
        if(~tree[t].fi) q.push(tree[t].fi);
        if(~tree[t].se) q.push(tree[t].se);
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n;i++) cin>>post[i];
    for(int i=0;i<n;i++) cin>>in[i],pos[in[i]]=i;

    int root=build(0,n-1,0,n-1);
    bfs(root);
    
    for(int i=0;i<cnt;i++)
    {
        if(i) cout<<' '<<level[i];
        else cout<<level[i];
    }

    //system("pause");
    return 0;
}

(update)
由于本题结点的值为1 ~ N,故pair数组也是可以直接存值的,如果结点值过大,就要采用上面那种存下标的方式了。

const int N=35;
PII tree[N];
int pos[N];
int post[N];
int in[N];
int n,cnt;

int build(int inl,int inr,int postl,int postr)
{
    if(postl>postr) return -1;
    
    int root=post[postr];
    int k=pos[root];
    
    int lchild=build(inl,k-1,postl,postl+k-inl-1);
    int rchild=build(k+1,inr,postl+k-inl,postr-1);
    tree[root]={lchild,rchild};
    return root;
}

void bfs(int root)
{
    queue<int> q;
    q.push(root);
    
    while(q.size())
    {
        int t=q.front();
        q.pop();
        
        if(cnt) cout<<' ';
        cout<<t;
        cnt++;
        
        if(~tree[t].fi) q.push(tree[t].fi);
        if(~tree[t].se) q.push(tree[t].se);
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n;i++) cin>>post[i];
    for(int i=0;i<n;i++) cin>>in[i],pos[in[i]]=i;

    int root=build(0,n-1,0,n-1);
    bfs(root);

    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/fxh0707/p/14322105.html