L2-011二分木の再生(25ポイント)
二分木のミドルオーダートラバーサルとプレオーダートラバーサルを前提として、最初にツリーのミラーインバージョンを作成してから、反転レイヤーオーダートラバーサルのシーケンスを出力してください。いわゆるミラー反転とは、すべての非リーフノードの左右の子を交換することを指します。キー値はすべて、互いに等しくない正の整数であると想定されています。
入力フォーマット:
最初の行を入力して、二分木のノード数である正の整数N(≤30)を指定します。2行目は、順序どおりの走査シーケンスを示しています。3行目は、プレオーダートラバーサルシーケンスを示しています。数字はスペースで区切られます。
出力フォーマット:
ツリーが1行で反転された後、ツリーが通過したシーケンスを出力します。数字はスペースで区切られ、行の最初と最後に余分なスペースがあってはなりません。
入力サンプル:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
サンプル出力:
4 6 1 7 5 3 2
問題解決
後続を確立する際に、dfs番号検索構造の場合、1次の順序で(dfsによって)取得できます。
次に、bfsプレオーダートラバーサルレイヤーが取得され、わずかに変更されます。
コード
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1e2 + 2;
vector<int> front, mid, back, layer;
typedef struct Node {
int value;
Node *left, *right;
} * Tree;
Tree dfs(int fl, int fr, int ml, int mr, Tree T) {
if(fl > fr) return NULL;
if(!T) T = new Node();
T->value = front[fl];
int len = 0; //表示左子树长度, 如果已知后序就表示右子树长度
int K; //记录中序的
for(int i = ml; i <= mr; i++) {
//如果已知后序就从mr向ml遍历
if(front[fl] == mid[i]) {
K = i;
break;
}
len++;
}
T->right = dfs(fl + 1, fl + len, ml, K - 1, T->right);
T->left = dfs(fl + len + 1, fr, K + 1, mr, T->left);
back.push_back(front[fl]);
return T;
}
void bfs(Tree T) {
queue<Tree> q;
q.push(T);
while(!q.empty()) {
Tree T = q.front();
q.pop();
layer.push_back(T->value);
if(T->left) q.push(T->left);
if(T->right) q.push(T->right);
}
}
int main() {
int N, a;
cin >> N;
for(int i = 0; i < N; i++) {
cin >> a;
mid.push_back(a);
}
for(int i = 0; i < N; i++) {
cin >> a;
front.push_back(a);
}
Tree T = dfs(0, front.size() - 1, 0, mid.size() - 1, NULL);
bfs(T);
for(int i = 0; i < layer.size(); i++) {
if(i) cout << " ";
cout << layer[i];
}
return 0;
}