PAT 1020 Tree Traversals (25 分)(后序中序构造二叉树+层次遍历输出)

题意

给你一棵树的后序遍历和中序遍历,求这棵树的层次遍历

思路

有两个问题
1.如何用后序和中序来构造一棵二叉树
2.如何层次遍历一颗二叉树

构造二叉树

已知后序的访问顺序为 左右根
中序的访问顺序问 左根右
那么对于一颗树来说后序的最后一个元素就是当前树的根,那么我们考虑每一颗子树,只要确定了子树的在后序中是那一部分,那这一部分的最后一个元素就是这颗子树的根了,那么正好我们可以通过中序来确定左右子树是哪些,举个例子,节点数为7的后序和中序,那么我们可以画出树来

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
             4
            /  \
          1      6
          \     /  \
          3    5    7
          /
         2

对于一开始的树来说后序的最后一个元素4就是整颗树的根,然后我们去中序中找左子树是哪些,右子树是哪些,发现 1 2 3 为其左子树且大小为3,5 6 7为其右子树且大小为三,那么对于左子树来说,由于后序是先遍历左,所以从开始的大小为3的元素都是左子树,那么我们知道2 3 1 为左子树的后序,根据后序的性质最后一个元素是根节点,那么我们就找到了,这颗左子树的根节点了,然后再去中序中寻找左子树的左右子树是哪些,发现其左子树的左子树为长度为0,说明左子树没有左子树了,左子树的右子树是2 3,然后就是重复上述的步骤,就可以用递归来做了就能构建出一颗二叉树了

层次遍历

层次遍历用队列代替栈然后依次对当前的节点的左儿子入队,右儿子入队就可以了

#include <bits/stdc++.h>
using namespace std;
typedef struct BiTNode
{
    int c;
    BiTNode *lchild,*rlchid;

} BiTNode,*BiTree;
int post[35];
int in[35];
int cnt;
BiTree build(int postL,int postR,int inL,int inR)
{
    BiTree T=new BiTNode;
    T->c=post[postR];
    int Lnum,Rnum,pos;
    for(int i=inL;i<=inR;i++)
    {
        if(post[postR]==in[i])
        {
            pos=i;
            Lnum=i-inL;
            Rnum=inR-i;
            break;
        }
    }
    if(Lnum)
    {
        T->lchild=build(postL,postL+Lnum-1,inL,pos-1);
    }
    else
        T->lchild=NULL;
    if(Rnum)
        T->rlchid=build(postR-Rnum,postR-1,pos+1,inR);
    else
        T->rlchid=NULL;
    return T;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&post[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&in[i]);
    BiTree T=build(0,n-1,0,n-1);
    queue<BiTree>q;
    int cnt=0;
    q.push(T);
    while(!q.empty())
    {
        T=q.front();
        q.pop();
        if(T!=NULL)
        {
            if(T->lchild!=NULL)
                q.push(T->lchild);
            if(T->rlchid!=NULL)
                q.push(T->rlchid);
        }
        if(cnt++!=n-1)
            printf("%d ",T->c);
        else
            printf("%d\n",T->c);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值