L2-006. 树的遍历
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:7 2 3 1 5 7 6 4 1 2 3 4 5 6 7输出样例:
4 1 6 3 5 7 2
思路:
已知中序与后序遍历,即可重建二叉树,后序遍历的特点就是先遍历左右子树再输出根节点的值,所以后序遍历序列最后一个节点就是根节点,而其左右子树的区间范围就可以在中序遍历中找,譬如样例的第一个根节点是4,找到4在中序遍历中的位置,4的左边就是左子树,右边就是右子树,继而分别对右子树和左子树
递归查找,要注意的是由于后序遍历根节点分布的位置,先递归查找右子树,再左子树。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; #define INF 0x3f3f3f3f #define EPS 1e-5 #define pi cos(-1) const int N_MAX = 10010; int n,pos; vector<int>in,post,level; struct Node { int key, L,R;//当前节点值以及左右子树的下标 Node() {} Node(int Key,int L,int R):key(Key),L(L),R(R) {} }; Node node[N_MAX]; void dfs(const int& l, const int& r,int n) {//找出[l,r]区间范围的根以及其左右子树 if (l > r) { node[n].key = INF;//值不存在,设为INF return; } int root = post[pos--]; node[n]=(Node(root,2*n+1,2*n+2));//记录根节点的值以及左右子树下标 int m = find(in.begin(),in.end(),root)-in.begin(); dfs(m+1, r,2*n+2);//先建右子树 dfs(l , m-1,2*n+1); } void bfs() { queue<int>que; que.push(0); while (!que.empty()) { int p = que.front();que.pop(); if (node[p].key != INF) { level.push_back(node[p].key); if (node[p].L != 0)que.push(node[p].L); if (node[p].R != 0)que.push(node[p].R); } } } int main() { scanf("%d", &n); in.resize(n); post.resize(n); for (int i = 0; i < n;i++) { cin >> post[i]; } for (int i = 0; i < n;i++) { cin >> in[i]; } pos = n - 1; dfs(0, n - 1, 0); bfs(); for (int i = 0; i < level.size();i++) { cout << level[i]; if (i + 1 == level.size())cout << endl; else cout << " "; } return 0; }