PTA 天梯赛 L2-006 树的遍历 C语言

题面

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

输入格式:

输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

4 1 6 3 5 7 2

相关知识

1.中序遍历:左子树->结点->右子树

2.后序遍历:左子树->右子树->结点

分析

由以上可知,后序遍历的最后一个数即为根结点,即样例中的 “4”,对应到中序遍历中,“4”左边的数组即为左子树,右边的数组即为右子树,左边数组中后序遍历下标最大的数即为左子树的子树根结点,同理右边也是一样。因此我们只要对中序遍历不断递归寻找每一个结点,并按层次记录结点键值,最后依次输出即可。

代码实现

#include<stdio.h>
#include <string.h>
struct tree{
    int arr[30];
    int num;//记录同层次结点数量
};//用于记录不同层次结点键值

int* max(int*,int*,int*);//用于寻找后序遍历中下标最大的值,并返回地址

void creat(int*,int,struct tree*,int*,int*);//用于递归查找结点

int main()
{
    int b,c=0;//b为结点数,c用于输出
    struct tree a[30];//定义每一层
    memset(a,0,sizeof(struct tree));//初始化结构体
    scanf("%d",&b);
    int lat[b];//后序遍历
    int hash[1000]={0};//用于记录后序遍历中键值对应的下标,便于查找比较
    int mid[b];//前序遍历
    for(int i=0; i<b; i++){
        scanf("%d",&lat[i]);
        hash[lat[i]]=i;//记录下标
    }
    for(int i=0; i<b; i++){
        scanf("%d",&mid[i]);
    }
    creat(hash,0,a,&mid[0],&mid[b-1]);
    while(1){//输出
        if(a[c].arr[0]==0) break;
        if(c==0) printf("%d",a[c++].arr[0]);
        else {
            for(int i=0; i<a[c].num; i++){
                printf(" %d",a[c].arr[i]);
            }
            c++;
        }
    }
    return 0;
}
void creat(int* hash,int b,struct tree* a,int* l,int* r){//用左右指针限制数组
    int* root=max(hash,l,r);//找结点
    int *p=root,*q=root;
    a[b].arr[ a[b].num++ ]=*root;//记录结点键值且计数加一
    if(l!=q){
        q--;
        creat(hash,b+1,a,l,q);//进入左子树
    }
    if(p!=r){
        p++;
        creat(hash,b+1,a,p,r);//进入右子树
    }
    return;
}
int* max(int* hash,int* p, int* q){
    int* p1=p;//用指针进行遍历
    int* p2;
    int maxi=-1;
    while(p1<=q){
        if(hash[*p1]>maxi){
            maxi=hash[*p1];
            p2=p1;//记录最大下标数的地址
        }
        p1++;
    }
    return p2;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值