一切的核心是怎么利用中序和按层遍历构建二叉树?
1.优化空间很大,可以提前预处理记录每个数对应的位置,还可以vis数组记录这个点是不是已经作为根了。
2.我们考虑到每次找到当前中序要处理区间,里面的数记为集合mid,我们从前到后看层序遍历中的哪个数最先出现在mid中。那么这个数就是当前中序处理区间的根,这个新根的左边是左子树,右边是右子树,我们可以递归处理。
3.对于叶子节点,就是当他作为根的时候,没有左右节点,也就无法进行进一步深搜,flag记一下就可以了。
#include<stdio.h>
#include<vector>
#include<map>
#include<algorithm>
#include <algorithm>
#include <iostream>
#include<string>
using namespace std;
vector<int> InOrder, LevelOrder;
vector<int>ans;
vector<int>ans1,ans2;
void getPreOder(int l1, int r1, int l2, int r2) {
int i, j;
//l1,r1_inorder
//l2,r2_levelorder
//在中序中找到层序遍历当前的根节点
for(i = l2; i <= r2; i++) {
bool flag = false;
for(j = l1; j <= r1; j++) {
if(LevelOrder[i] == InOrder[j]) {
// cout << LevelOrder[i]<<" ";
ans1.push_back(LevelOrder[i]);
flag = true;
break;
}
}
if(flag) break;
}
bool flag=false;
if(j > l1) {getPreOder(l1, j - 1, 0, r2);flag=true;}
if(j < r1) {getPreOder(j + 1, r1, 0, r2);flag=true;}
if(!flag)ans.push_back(LevelOrder[i]);
}
// 递归构造后序遍历字符串
void getPostOrder(int l1, int r1, int l2, int r2) {
int i, j;
for(i = l2; i <= r2; i++) {
bool flag = false;
// 在中序遍历中找到当前层次遍历结点对应的位置
for(j = l1; j <= r1; j++) {
if(LevelOrder[i] == InOrder[j]) {
flag = true;
break;
}
}
if(flag) break;
}
// cerr<<InOrder[j]<<endl;
// 递归处理左子树
if(j > l1) getPostOrder(l1, j - 1, 0, r2);
// 递归处理右子树
if(j < r1) getPostOrder(j + 1, r1, 0, r2);
// 输出当前根节点的值
ans2.push_back(InOrder[j]);
//cout << InOrder[j]<<" ";
}
int main() {
int n;
cin>>n;
// 读入层次遍历的字符串
for(int i=0;i<n;i++){
int x;cin>>x;
LevelOrder.push_back(x);
}
//中序遍历
for(int i=0;i<n;i++){
int x;cin>>x;
InOrder.push_back(x);
}
// 调用 getPostOrder 函数并传入整棵树的中序遍历区间和层次遍历区间
getPreOder(0, InOrder.size() - 1, 0, LevelOrder.size() - 1);
//cout<<endl;
getPostOrder(0, InOrder.size() - 1, 0, LevelOrder.size() - 1);
//cout<<endl;
for(auto x:ans)cout<<x<<" ";cout<<endl;
for(auto x:ans1)cout<<x<<" ";cout<<endl;
for(auto x:ans2)cout<<x<<" ";cout<<endl;
return 0;
}
标签:求该,遍历,r1,int,中序,l1,include
From: https://www.cnblogs.com/mathiter/p/17924691.html