题目描述
给定前序和中序遍历顺序,求镜像后的层序遍历顺序
思路
首先根据前序遍历和和中序遍历构造二叉树,再通过bfs层序遍历二叉树。难点在于构建二叉树,经分析,容易得知前序遍历的第一个元素是根节点,再通过中序遍历的这个点的位置看两边,很明显这是个多个共同子问题(适合用分治),最小情况下是前序数组只有1个元素既只剩一个根节点,而中序数组有三种可能,但是都是可以统一处理的。
代码实现
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
using namespace std;
struct node{
int val;
node *left;
node *right;
};
int n,pre[1000],ino[1000]; //pre :前序数组, ino:中序数组
node *recreate(int postL , int postR , int inL , int inR){ //前序区间左下标,右下标 ,中序左下标,右下标
if (postL > postR) return NULL;
node* root = new node;
root->val = pre[postL]; //子树的根节点
int k;
for (k = inL ; k <= inR ; k++){ //找到在中序数组中的根节点下标
if (ino[k] == root->val){
break;
}
}
int numsize = k-inL;//元素个数
//重点 ,可以画图好理解点的
//对应前序区间[postL+1,postL+numsize] 中序[inL,k-1]
//前序要跳过第一个节点,因为是传的下标,所以要更新长度,中序要跳过根节点;
root->left = recreate(postL+1,postL+numsize,inL,k-1);
//对应前序区间[postL+1+numsize,postR] 中序[inL,k-1]
root->right = recreate(postL+1+numsize,postR,k+1,inR);
return root;
}
void dfs(node *root){
if (root== NULL){
return;
}
cout << root->val << endl;
dfs(root->left);
dfs(root->right);
}
void bfs(node* root){
queue<node*>q;
q.push(root);
int i = 0;
while (!q.empty()){
node *t = q.front();
q.pop();
if (++i == 1){
cout << t->val;
}
else cout << " " << t->val;
if (t->right != NULL)q.push(t->right);//翻转则是对调左子树和右子树加入队列的先后即可
if (t->left != NULL)q.push(t->left);
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1 ; i <= n ; i++){
cin >> ino[i];
}
for (int i = 1 ; i <= n ; i++){
cin >> pre[i];
}
node *root = recreate(1,n,1,n);
// cout << root->val << endl;
bfs(root);
return 0;
}
OVER