后序遍历与中序遍历确定树,PAT A1020

PAT 1020
利用后序遍历和中序遍历建树并用层序遍历输出这棵树
原题翻译后为:
在这里插入图片描述
在这里插入图片描述
详细代码和注释:

/**
 * 题目就是给出树的后续和中序遍历
 * 求出这颗树,并用层序遍历输出结果
 */
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;

const int maxn=50;

//创建节点对象
struct node{
    int data;       //数据域
    node *lchild;
    node *rchild;
};

int pre[maxn],in[maxn],post[maxn];      //在程序的外部把先序、中序、后序的数组给定义好
int n;  //节点个数

//当前二叉树的后续遍历区间为[postL,postR],中序遍历的序列为[inL,inR]
//create函数返回构建出的二叉树的根结点的地址
//参数我只要序列的左右数据即可,不需要有节点的地址等信息
node* create(int postL,int postR,int inL,int inR){
    //递归边界
    if (postL>postR)
    {
        return NULL;        //后序序列长度小于0时,直接返回为NULL
    }
    //新建一个新的节点,用来存放当前二叉树的根节点
    node* root = new node;
    //完善结构体的信息
    root->data=post[postR];
    root->lchild=NULL;
    root->rchild=NULL;

接下来是查找中序遍历中的位置在哪里,以确定左子树和右子树
    int k,numLeft;
    for ( k=inL ; k<=inR; k++)
    {
        if (post[postR]==in[k])
        {
            numLeft=k-inL;
            break;
        }
    }

    root->lchild=create(postL,postL+numLeft-1,inL,inL+numLeft-1);
    root->rchild=create(postL+numLeft,postR-1,inL+numLeft+1,inR);

    return root;
}

//层序遍历访问刚刚建好的树结构
int num=0;   //定义一个变量目的是表示已经输出的结点的个数以便最后一个节点后不输出空格

//层序遍历输出结果
void BFS(node *root){
    //建立一个队列
    queue<node*> q;
    //队列的最常见用法是干什么的?
    //将根节点加入到队列中,然后从中取出去,将它的子孙节点再放入队列中
    q.push(root);
    node *tmp_node=NULL;
    //栈、队列使用前都需要验证是否为空
    while (!q.empty())
    {

        tmp_node = q.front();
        //弹出队首元素
        q.pop();
        printf("%d",tmp_node->data);
        //已经输出的节点个数
        num++;
        if (num<n) printf(" ");

        //放入子孙节点
        if ( tmp_node->lchild!=NULL) q.push(tmp_node->lchild);  //左子树非空放入左子树
        if ( tmp_node->rchild!=NULL) q.push(tmp_node->rchild);  //右子树非空放入右子树

    }
    

}

int main(){
    scanf("%d",&n);
    int tmp;
    for (int i = 0; i < n; i++)
    {
        scanf("%d",&tmp);
        post[i]=tmp;
    }
     for (int i = 0; i < n; i++)
    {
        scanf("%d",&tmp);
        in[i]=tmp;
    }
    
    node *tree=create(0,n-1,0,n-1);
    BFS(tree);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值