pta - 树的遍历(已知后序和中序,求层序遍历)

样例:
7
2 3 1 5 7 6 4(后序-左右根)
1 2 3 4 5 6 7(中序-左根右)

后序遍历的最后一个节点一定是根节点 (先设 last = n-1) ,所以在中序遍历中等于根节点的元素左右两侧分别是左子树和右子树,last–,再递归建右子树和左子树.
层序遍历就是借助队列来输出,先进先出.
一开始理解怎么建树但是就是自己写不出来…最后还是看了别人的代码看了很久才理解的差不多…太菜了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <cmath>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int maxn = 1e4+10;
int a[50];
int b[50];
typedef struct node
{
    int data;
    struct node *l,*r;
}*tree;
int n;
queue<tree>q;

void creat(tree &t,int pre,int last,int len)//t,0,n-1,n
{
    int inx;
    int lenl,lenr;
    if(len<=0)
    {
        t=NULL;
        return;
    }
    else
    {
        t = (struct node*)malloc(sizeof(struct node));
        t->data = a[last];
        for(int i=0; i<n; i++)
        {
            if(b[i]==a[last])
            {
                inx = i;
                break;
            }
        }
        lenr = len-(inx-pre)-1;
        creat(t->r,inx+1,last-1,lenr);
        //右子树,右子树的起点,右序遍历后移的坐标,剩下节点的个数
        lenl = inx-pre;
        creat(t->l,pre,last-lenr-1,lenl);
    }
    return;
}

void ceng(tree t)
{
    tree tt = t;
    q.push(tt);
    while(!q.empty())
    {
        tt = q.front();
        cout<<tt->data;
        if(tt->l!=NULL)
        {
            q.push(tt->l);
        }
        if(tt->r!=NULL)
        {
            q.push(tt->r);
        }
        q.pop();
        if(!q.empty())
        {
            cout<<" ";
        }
        else
        {
            cout<<endl;
        }
    }
    return;
}

int main()
{
    cin>>n;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
    }
    for(int i=0; i<n; i++)
    {
        cin>>b[i];
    }
    tree t = NULL;
    creat(t,0,n-1,n);
    ceng(t);
    return 0;
}

在递归建树时那几个参数的意思想了很久才明白😫.下面的注释我也有可能理解错了,如果错了恳请指出.

		lenr = len-(inx-pre)-1;//右子树剩余的节点数
		
        creat(t->r,inx+1,last-1,lenr);
        
        //右子树,右子树的起点,右子树根节点在后序遍历中的坐标,右子树剩下节点的个数
        
        lenl = inx-pre;//左子树剩余的节点数
        
        creat(t->l,pre,last-lenr-1,lenl);
        //左子树 左子树的起点, 左子树根节点在后序遍历中的坐标, 左子树剩下的节点数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值