L2-011 玩转二叉树 (25分)
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2
解题
由后序,中序可得先序(通过dfs),同时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;
}