【Acwing】【Blue Bridge Cup Training】【Rekursiv】

Baumdurchquerung

Ein Binärbaum, in dem sich die Gewichte der einzelnen Knoten im Baum voneinander unterscheiden.

Geben Sie nun angesichts der Durchquerung nach der Reihenfolge und der Durchquerung in der Reihenfolge die Durchquerung in der Ebenenreihenfolge aus.

Eingabeformat

Die erste Zeile enthält die ganze Zahl N, die Anzahl der Knoten im Binärbaum.

Die zweite Zeile enthält N Ganzzahlen, die die Durchquerung des Binärbaums nach der Reihenfolge darstellen.

Die dritte Zeile enthält N ganze Zahlen, die den Durchlauf des Binärbaums in der Reihenfolge darstellen.

Ausgabeformat

Geben Sie eine Zeile mit N Ganzzahlen aus, die die Durchquerung der Ebenenreihenfolge des Binärbaums darstellt.

Datenreichweite

1 ≤ N ≤ 30
Der Beamte gibt den Wertebereich des Gewichts jedes Knotens nicht an. Der Einfachheit halber wird der Umfang dieser Website mit 1∼N angenommen.

Eingabebeispiel:

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

Beispielausgabe:

4 1 6 3 5 7 2
后序:2  3  1  5  7  6  4			
中序:1  2  3  4  5  6  7
    
后序的最后一个是整棵数的根节点. k表示在根在中序中的位置下标
递归创建左右子树
设后序中左子树的右端点为x:x - pl = k - 1 - il --> x = pl + k - 1 - il
l[root] = build(il, k - 1, pl, pl + k - 1 - il)
后序中右子树的左端点为左子树的右端点+1:
r[root] = build(k + 1, ir, pl + k - il, pr - 1)

Fügen Sie hier eine Bildbeschreibung ein

#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
const int N = 40;
int postorder[N], inorder[N]; // 后序序列和中序序列
// l存每个点的左儿子, r存每个点的右儿子, pos存中序遍历中每个值对应的下标
unordered_map<int, int> l, r, pos;

// 建立二叉树(参数是中序区间和后序区间)
int build(int il, int ir, int pl, int pr)
{
    
    
    int root = postorder[pr]; // 根节点是后序的最后一个
    int k = pos[root]; // 找到根节点在中序中的下标k
    // 判断左子树存在,递归创建左子树
    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)
{
    
    
    queue<int> q;
    q.push(root);
    while (q.size())
    {
    
    
        auto t = q.front();
        q.pop();
        cout << t << ' ';
        if (l.count(t)) q.push(l[t]);
        if (r.count(t)) q.push(r[t]);
    }
}

int main()
{
    
    
    int n; 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;
}

Guess you like

Origin blog.csdn.net/laaa123mmm/article/details/129470274