PTA L2-011二分木で遊ぶ(ツリーの走査+改善コード)

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;
}

おすすめ

転載: blog.csdn.net/qq_45349225/article/details/110100427