https://pintia.cn/problem-sets/994805046380707840/exam/problems/994805069361299456?type=7&page=1
题意:
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。
后
4 4
6 6
7 7
5 5
1 1
3 3
2 2
1 2 3 4 5 6 7 :中序
答案: 4163572
const int N = 35;
int post[N], mid[N]; //后序和中序
int r[N], l[N]; //模拟左右链表
queue<int>c;
void dfs(int i, int j, int x, int y, int * a)
//中序的起点和终点, 后序的起点和终点,根节点
{
if(i == j)
{
*a = i;
return;
}
int t = i;
while(mid[t] != post[y]) t ++;
//因为后序的终点一定是根节点,
//现在要在中序中找到根节点的位置,以作为左右子树的分割
*a = t; //将t赋值给a的指针域,第一次根节点
if(t == i) //没有左子树,直接搜右子树
dfs(i + 1, j, x, y - 1, &r[t]);
else if(t == j) //没有右子树,直接搜左子树
dfs(i, j - 1, x, y - 1, &l[t]);
else //搜左右子树
{
//后序中前半部分是左子树,右半部分是右子树
dfs(i, t - 1, x, x + t - i - 1, &l[t]);
dfs(t + 1, j, x + t - i, y - 1, &r[t]);
}
}
void rankorder(int u)
{
c.push(u);
while(!c.empty())
{
int h = c.front(); //从队首开始遍历左右孩子
if(mid[l[h]]) //如果左孩子存在就输出
{
c.push(l[h]);
cout << " " << mid[l[h]];
}
if(mid[r[h]])
{
c.push(r[h]);
cout << " " << mid[r[h]];
}
c.pop();
}
}
void solved()
{
int n; cin >> n;
for(int i = 0; i < n; i ++) cin >> post[i];
for(int i = 0; i < n; i ++) cin >> mid[i];
memset(l, -1, sizeof l);
memset(r, -1, sizeof r);
int root;
dfs(0, n - 1, 0, n - 1, &root);
cout << mid[root] ;
rankorder(root);
}