PAT甲级真题1020 树的遍历

题面

在这里插入图片描述

题解

  1. 根据前序/后序 和 中序 遍历结果,我们都可以还原这颗二叉树,因为前序(根左右),中序(左根右),后序(左右根),我们根据树根所在的位置,就可以得出树的左右儿子,只要递归处理,我们就可以还原整颗树 ,注意的是区间的边界问题,可以直接列出数字来确定,这样不容易出错
  1. 当建树完成后,我们只需要从根节点进行BFS就可以实现层序遍历

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<unordered_map>
#include<queue>

using namespace std;
const int N = 35;

int n, x;
//前序/中序/后序 preorder/inorder/postorder
vector<int> inorder, postorder;
unordered_map<int, int> mp;

struct TreeNode {
    
    
    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode(int x) : val(x), left(NULL), right(NULL) {
    
    }
};


TreeNode *dfs(int il, int ir, int pl, int pr) {
    
    
    if (pl > pr) return NULL;
    int k = mp[postorder[pr]];  //中序遍历的根节点下标
    TreeNode *root = new TreeNode(inorder[k]);
    root->left = dfs(il, k - 1, pl, pl + k - il - 1);
    root->right = dfs(k + 1, ir, pl + k - il, pr - 1);
    return root;
}


TreeNode *buildTree() {
    
    
    for (int i = 0; i < n; i++) {
    
    
        mp[inorder[i]] = i;
    }
    return dfs(0, n - 1, 0, n - 1);
}

int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    cin >> n;
    for (int i = 0; i < n; i++) {
    
    
        cin >> x;
        postorder.push_back(x);
    }
    for (int i = 0; i < n; i++) {
    
    
        cin >> x;
        inorder.push_back(x);
    }

    TreeNode *root = buildTree();  //建树,返回根节点

    //款搜进行层序遍历
    queue<TreeNode> q;
    q.push(*root);
    vector<int> res;
    while (q.size()) {
    
    
        auto t = q.front();
        q.pop();
        res.push_back(t.val);
        if (t.left != nullptr) q.push(*t.left);
        if (t.right != nullptr) q.push(*t.right);
    }

    for (int i = 0; i < n; i++) {
    
    
        if (i != n - 1) {
    
    
            cout << res[i] << " ";
        } else {
    
    
            cout << res[i] << endl;
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/115112221