已知一棵树的后序遍历顺序和中序遍历顺序,求层次遍历的顺序;
树的四种遍历:
先序遍历:先访问根节点,再访问左子树,最后访问右子树
中序遍历:先访问左子树,再访问根节点,最后访问右子树
后序遍历:先访问左子树,再访问右子树,最后访问根节点
层次遍历:一层一层的访问;
完全二叉树的节点关系,在层次遍历中假设根节点的编号是n,左子树的根节点是2*n,右边是2*n+1;
本题是已知后序a和中序b:
由于后序遍历最后访问根节点所以,数组a的最后一个节点一定是根节点,然后在数组b中找到根节点的位置,该位置左边部分一定是该节点的左子树,右边部分一定是右子树的部分,然后根据左边的元素找到在a中的对应位置,靠后面的那个就是子树的根节点,一次递归下去即可;
注意的就是对应区间在a和b数组上的位置关系;
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include <map> #include <vector> using namespace std; #define N 31 #define INF 0x3f3f3f3f int a[N], b[N], n, p; ///a数组保存后序,b保存中序,c.num保存层次,c.pos是当这个数是完全二叉树时的位置; struct node { int pos, num; }c[300]; void dfs(int aL, int aR, int pos, int bL, int bR) { if(bL > bR || aL > aR) { //c[pos] = -INF; return; } //c[pos] = a[aR]; c[p].num = a[aR]; c[p++].pos = pos; for(int i=bL; i<=bR; i++) { if(b[i] == a[aR])///根节点是a[aR]; { dfs(aL, aL+i-bL-1, pos*2, bL, i-1);///当前根节点左子树在a数组中的下标是[aL, aL+i-bL-1],在b中的是[bL, i-1]; dfs(aR-(bR-i), aR-1, pos*2+1, i+1, bR);///当前根节点右子树在a数组中的下标是[aL-(bR-i), aR-1],在b中的是[bL, i-1]; } } } int cmp(node p, node q) { return p.pos < q.pos; } int main() { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &a[i]); for(int i=1; i<=n; i++) scanf("%d", &b[i]); p = 0; dfs(1, n, 1, 1, n); sort(c, c+p, cmp);///按编号进行排序; int flag = 0; for(int i=0; i<p; i++) { if(flag == 0) { printf("%d", c[i].num); flag = 1; } else printf(" %d", c[i].num); } printf(" "); return 0; }