1020 树的遍历

一个二叉树,树中每个节点的权值互不相同。

现在给出它的后序遍历和中序遍历,请你输出它的层序遍历。

输入格式

第一行包含整数 N,表示二叉树的节点数。

第二行包含 N 个整数,表示二叉树的后序遍历。

第三行包含 N 个整数,表示二叉树的中序遍历。

输出格式

输出一行 N 个整数,表示二叉树的层序遍历。

数据范围

1N30,
官方并未给出各节点权值的取值范围,为方便起见,在本网站范围取为 1N

输入样例:

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

输出样例:

4 1 6 3 5 7 2

代码实现:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <queue>

using namespace std;

const int N = 40;

int n,count1;
int postorder[N], inorder[N];               //后序遍历,中序遍历
unordered_map<int, int> l, r, pos;          //用哈希表模拟二叉树

int build(int il, int ir, int pl, int pr)
{
	if(il>ir||pl>pr) return 0; 
    int root = postorder[pr];
    int k = pos[root];                      //得到根节点在中序遍历中的下标

    //k大于il表示根节点左边还有节点,即当前根节点存在左子树,下同
    //下面两行是难点,举例解释见图
	if(il<k)l[root] = build(il, k - 1, pl, pl + k - 1 - il);
	if(ir>k)r[root] = build(k + 1, ir, pl + k - il, pr - 1);

    return root;
}

void bfs(int root)                          //BFS用来层序遍历输出
{
    queue<int> q;
    q.push(root);
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        if(count1==0)cout<<t;
        else cout <<" "<<t;
        count1++;
        if (l[t]) q.push(l[t]);       //判断该节点的左右儿子是否存在
        if (r[t]) q.push(r[t]);       //存在则加入队列,等待下一层遍历
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> postorder[i];
    for (int i = 0; i < n; i ++ )
    {
        cin >> inorder[i];
        pos[inorder[i]] = i;                //记录中序遍历每个点位置(剪枝)
    }

    int root = build(0, n - 1, 0, n - 1);   //参数为中序遍历区间和后序遍历区间
    bfs(root);

    return 0;
}

 

posted @ 2023-04-20 18:07  回忆、少年  阅读(12)  评论(0编辑  收藏  举报