1. 程式人生 > 其它 >中序和後序確定層序

中序和後序確定層序

L2-006 樹的遍歷 (25 分)

題意:

給出中序和後序遍歷 輸出層序遍歷

思路:

後序可以確定根節點

中序根節點前面的數是根節點左兒子的子集 而根節點右邊的數是其右兒子的子集

遞迴確定每棵子樹的根節點

記錄父子關係 然後遍歷二叉樹存圖輸出

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define ll long long
ll n;
ll zx[50], hx[50], ans[50];
struct node {
    ll l, r;
}fa[
50];
// zxl zxr hxl hxr 分別代表中序遍歷和後序遍歷的左右區間 ll find(ll zxl, ll zxr, ll hxl, ll hxr) {
//當中序左邊界大於有邊界時說明不能繼續下去了 不能等於應為當等於時可能左右兒子中有一個兒子不存在
if (zxl > zxr) return 0;
//記錄根 ll root
= hx[hxr]; ll p1 = zxl;
//記錄根的位子
while (zx[p1] != root) { p1++; }
//p2代表左子樹節點的個數 中序遍歷的左子樹元素集等於後序遍歷區段前p2個元素 ll p2
= p1 - zxl; fa[root].l = find(zxl, p1 - 1, hxl, hxl + p2 - 1); fa[root].r = find(p1 + 1, zxr, hxl + p2, hxr - 1); return root; } void solve() { cin >> n; for (int i = 1; i <= n; i++) { cin >> hx[i]; } for (int i = 1; i <= n; i++) { cin
>> zx[i]; } ll x = find(1, n, 1, n);
//存層序遍歷的圖 queue
<ll>q; ll tot = 0; q.push(hx[n]); while (!q.empty()) { ll now = q.front(); q.pop(); ans[++tot] = now; if(fa[now].l) q.push(fa[now].l); if(fa[now].r) q.push(fa[now].r); }
//輸出
for (int i = 1; i <= tot; i++) { cout << ans[i] << " \n"[i == tot]; } } signed main() { IOS; int t = 1; //cin >> t; while (t--) { solve(); } }