GPLT L2-006 树的遍历(二叉树)

题意:

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

思路:

后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点。

中序遍历序列 = 左子树遍历序列 + 根节点 + 右子树遍历序列。

找到根节点,再利用根节点计算新的后、中遍历序列端点。

Tips:

注意建树时传根节点的引用。

#include <bits/stdc++.h>
using namespace std;

const int M=35;
int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历

map<int,int> posb;//后序遍历中某点在中序遍历中的位置

struct Bt{//二叉树结点
    int v;
    Bt *l,*r;
}*root;

void build_tree(Bt* & rt,int l1,int r1,int l2,int r2){//l1~r1为该树的后序遍历序列区间,l2~r2为中序遍历序列区间。
    if(l1>r1||l2>r2){//若不存在有效遍历
        rt=nullptr;
        return;
    }
    rt=new(Bt);
    rt->v=a[r1];//后序倒数第一个即为该子树的根节点
    int mid=posb[a[r1]];//该端点在中序遍历中的位置
    int len=mid-l2;//左子树的长度
    build_tree(rt->l,l1,l1+len-1,l2,mid-1);//递归建立左子树
    build_tree(rt->r,l1+len,r1-1,mid+1,r2);//递归建立右子树
}

void Print_level(Bt* t){
    queue<Bt*> q;
    cout<<(t->v);
    if(t->l!=nullptr) q.push(t->l);
    if(t->r!=nullptr) q.push(t->r);
    while(!q.empty()){
        Bt* t=q.front();
        q.pop();
        if(t!=nullptr){
            cout<<' '<<(t->v);
            if(t->l!=nullptr) q.push(t->l);
            if(t->r!=nullptr) q.push(t->r);
        }
    }
}

int main(){
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    for(int i=0;i<n;i++){
        cin>>b[i];
        posb[b[i]]=i;
    }
    build_tree(root,0,n-1,0,n-1);
    Print_level(root);
    return 0;
}

 最初的做法:

#include <bits/stdc++.h>
using namespace std;

const int M=35;

struct Bt{
    int v;
    Bt *l,*r;
};

int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历 
map<int,int> posa,posb;//某值在后序、中序遍历中的位置

Bt *root;

void build_node(Bt* & pre,int last,int l,int r){//last为根节点的位置,l~r为中序遍历的左右端点
    pre=new(Bt);
    pre->v=a[last];

    int mid=posb[a[last]];//查找在中序遍历的位置
    int last1=-1,last2=-1;
    int l1=l,r1=mid-1;//计算根节点两边区间的端点
    int l2=mid+1,r2=r;

    for(int i=l1;i<=r1;i++)//枚举该子树结点在后序遍历中的位置,最大值即为该子树根节点的位置
        last1=max(last1,posa[b[i]]);
    for(int i=l2;i<=r2;i++)
        last2=max(last2,posa[b[i]]);

    if(l1<=r1)//如果中序遍历区间有效,继续建立子树结点
        build_node(pre->l,last1,l1,r1);
    else
        pre->l=nullptr;
    if(l2<=r2)
        build_node(pre->r,last2,l2,r2);
    else
        pre->r=nullptr;
}

void Print_level(Bt* t){
    queue<Bt*> q;

    cout<<(t->v);
    if(t->l!=nullptr) q.push(t->l);
    if(t->r!=nullptr) q.push(t->r);

    while(!q.empty()){
        Bt* t=q.front();
        q.pop();
        
        if(t!=nullptr){
            cout<<' '<<(t->v);
            if(t->l!=nullptr) q.push(t->l);
            if(t->r!=nullptr) q.push(t->r);
        }
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n;i++){
        cin>>a[i];
        posa[a[i]]=i;
    }

    for(int i=0;i<n;i++){
        cin>>b[i];
        posb[b[i]]=i;
    }

    build_node(root,n-1,0,n-1);

    Print_level(root);

    return 0;
}
原文地址:https://www.cnblogs.com/Kanoon/p/12489795.html