第一次做不出来,学习了柳神的解法
pre函数的参数 root:根节点在后序中的位置;
start:子树在中序中开始位置序号;end:子树在中序中结束的位置序号
index:从0开始,每个节点的序号 左边是2*index+1,右边是2*index;
层序遍历即可按照index从小到大的顺序输出
#include <iostream>
#include "map"
#include "vector"
#include "algorithm"
using namespace std;
vector<int> pos,in;
map<int,int> m;
void pre(int root,int start,int end,int index){
if (start>end) return;
int i = start;
while (i<end && in[i]!=pos[root]) i++;
m[index] = pos[root];
pre(root-1-end+i,start,i-1,2*index+1);
pre(root-1,i+1,end,2*index+2);
}
int main() {
int mm,temp;
scanf("%d\n",&mm);
pos.resize(mm);
in.resize(mm);
for (int i = 0; i < mm; ++i) {
scanf("%d",&pos[i]);
}
for (int i = 0; i < mm; ++i) {
scanf("%d",&in[i]);
}
pre(mm-1,0,mm-1,0);
auto i = m.begin();
printf("%d",i->second);
while (++i != m.end()) printf(" %d",i->second);
}
这样结合算法笔记上的代码好像更好理解一些:
[postL,postR]当前二叉树的后序序列区间,[inL,inR]当前二叉树的中序序列区间,index表示当前元素序号
#include <iostream>
#include "map"
#include "vector"
#include "algorithm"
using namespace std;
vector<int> pos,in;
map<int,int> m;
//void pre(int root,int start,int end,int index){
// if (start>end) return;
// int i = start;
// while (i<end && in[i]!=pos[root]) i++;
// m[index] = pos[root];
// pre(root-1-end+i,start,i-1,2*index+1);
// pre(root-1,i+1,end,2*index+2);
//}
//[postL,postR]当前二叉树的后序序列区间,[inL,inR]当前二叉树的中序序列区间,index表示当前元素序号
void pre(int postL,int postR,int inL,int inR,int index){
if(inL > inR) return;
int i = inL;
while (i<=inR && in[i]!=pos[postR]) i++;
m[index] = pos[postR];
int numleft = i - inL;
pre(postL,postL+numleft-1,inL,i-1,2*index+1);
pre(postL+numleft,postR-1,i+1,inR,2*index+2);
}
int main() {
int mm,temp;
scanf("%d\n",&mm);
pos.resize(mm);
in.resize(mm);
for (int i = 0; i < mm; ++i) {
scanf("%d",&pos[i]);
}
for (int i = 0; i < mm; ++i) {
scanf("%d",&in[i]);
}
pre(0,mm-1,0,mm-1,0);
auto i = m.begin();
printf("%d",i->second);
while (++i != m.end()) printf(" %d",i->second);
}