根据二叉树--前/后序遍历和中序遍历--还原二叉树
////前序+中序,还原二叉树
int n;
typedef struct tree{
int lc,rc;
}tree;
vector<tree> vct(100005);
int pre[40],mid[40],vis[40];
void f(int idxroot){ //根据前序遍历和中序遍历还原二叉树
if(idxroot==n+1) return;
int root=pre[idxroot];
map<int,int> lcmp,rcmp; //当前节点的左孩子集合和右孩子集合
int idxcur=0;
for(int i=1;i<=n;i++){ //先在mid找到当前root
if(mid[i]==root){
idxcur=i;
break;
}
}
for(int i=idxcur-1;i>=1;i--){ //记录左孩子集合
if(vis[mid[i]]) break;
lcmp[mid[i]]=1;
}
for(int i=idxcur+1;i<=n;i++){ //记录右孩子集合
if(vis[mid[i]]) break;
rcmp[mid[i]]=1;
}
for(int i=1;i<=n;i++){ //在前序遍历中遇到的第一个左孩子集合中的点,就是root的左孩子;右孩子同理
if(lcmp[pre[i]]&&vct[root].lc==0){
vct[root].lc=pre[i];
vis[pre[i]]=1;
}
else if(rcmp[pre[i]]&&vct[root].rc==0){
vct[root].rc=pre[i];
vis[pre[i]]=1;
break;
}
}
f(idxroot+1);
}
这个是自己在写题:7-12 玩转二叉树 - SMU 2024 spring 天梯赛4(补题) (pintia.cn)的时候研究的,不知道是不是完全正确,可能这题数据不太强,能AC。
////后序+中序,还原二叉树
int n;
typedef struct tree{
int lc,rc;
}tree;
vector<tree> vct(100005);
int last[40],mid[40],vis[40];
void f(int idxroot){ //根据前序遍历和中序遍历还原二叉树
if(idxroot==0) return;
int root=last[idxroot];
map<int,int> lcmp,rcmp; //当前节点的左孩子集合和右孩子集合
int idxcur=0;
for(int i=1;i<=n;i++){ //先在mid找到当前root
if(mid[i]==root){
idxcur=i;
break;
}
}
for(int i=idxcur-1;i>=1;i--){ //记录左孩子集合
if(vis[mid[i]]) break;
lcmp[mid[i]]=1;
}
for(int i=idxcur+1;i<=n;i++){ //记录右孩子集合
if(vis[mid[i]]) break;
rcmp[mid[i]]=1;
}
for(int i=n;i>=1;i--){ //从n到1遍历last,遇到的第一个左,右集合中的点即是其lc,rc.
if(rcmp[last[i]]&&vct[root].rc==0){
vct[root].rc=last[i];
vis[last[i]]=1;
}
if(lcmp[last[i]]&&vct[root].lc==0){
vct[root].lc=last[i];
vis[last[i]]=1;
break;
}
}
f(idxroot-1);
}
两者大同小异。