天梯赛练习题L2-006. 树的遍历

题目链接

已知一棵树的后序遍历顺序和中序遍历顺序,求层次遍历的顺序;

树的四种遍历:

先序遍历:先访问根节点,再访问左子树,最后访问右子树

中序遍历:先访问左子树,再访问根节点,最后访问右子树

后序遍历:先访问左子树,再访问右子树,最后访问根节点

层次遍历:一层一层的访问;

 

完全二叉树的节点关系,在层次遍历中假设根节点的编号是n,左子树的根节点是2*n,右边是2*n+1;

 

本题是已知后序a和中序b:

 由于后序遍历最后访问根节点所以,数组a的最后一个节点一定是根节点,然后在数组b中找到根节点的位置,该位置左边部分一定是该节点的左子树,右边部分一定是右子树的部分,然后根据左边的元素找到在a中的对应位置,靠后面的那个就是子树的根节点,一次递归下去即可;

注意的就是对应区间在a和b数组上的位置关系;

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include <map>
#include <vector>
using namespace std;

#define N 31
#define INF 0x3f3f3f3f

int a[N], b[N], n, p;
///a数组保存后序,b保存中序,c.num保存层次,c.pos是当这个数是完全二叉树时的位置;
struct node
{
    int pos, num;
}c[300];

void dfs(int aL, int aR, int pos, int bL, int bR)
{
    if(bL > bR || aL > aR)
    {
        //c[pos] = -INF;
        return;
    }

    //c[pos] = a[aR];
    c[p].num = a[aR];
    c[p++].pos = pos;

    for(int i=bL; i<=bR; i++)
    {
        if(b[i] == a[aR])///根节点是a[aR];
        {
            dfs(aL, aL+i-bL-1, pos*2, bL, i-1);///当前根节点左子树在a数组中的下标是[aL, aL+i-bL-1],在b中的是[bL, i-1];
            dfs(aR-(bR-i), aR-1, pos*2+1, i+1, bR);///当前根节点右子树在a数组中的下标是[aL-(bR-i), aR-1],在b中的是[bL, i-1];
        }
    }
}

int cmp(node p, node q)
{
    return p.pos < q.pos;
}

int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; i++)
        scanf("%d", &a[i]);
    for(int i=1; i<=n; i++)
        scanf("%d", &b[i]);

    p = 0;

    dfs(1, n, 1, 1, n);

    sort(c, c+p, cmp);///按编号进行排序;

    int flag = 0;

    for(int i=0; i<p; i++)
    {
        if(flag == 0)
        {
            printf("%d", c[i].num);
            flag = 1;
        }
        else
            printf(" %d", c[i].num);
    }
    printf("
");

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/6601605.html