题目
7-10 树的遍历
分数 25
全屏浏览
切换布局
作者 陈越
单位 浙江大学
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
解题原理
还原树
已知一棵树的后序遍历和中序遍历能够还原整个树。
假设根节点是r,它的左子树是L,右子树是R,则其后序遍历是LRr,中序遍历是LrR,其中LR都是暂时乱序的。唯一可以确定的是根节点,一定是后序遍历的最后一个元素。
据此在中序遍历中找到该根节点r,可以发现位置左边元素全部来自其左子树,右边元素全部来自其右子树。
例如:
后序:2 3 1 5 7 6 4
中序:1 2 3 4 5 6 7
后序最后一个元素是4,则根节点是4,划分中序为:
1 2 3 |4| 5 6 7
那么左子树有三个元素,右子树有三个元素,再据此划分后序遍历:
2 3 1 |5 7 6 |4
那么右子树的后序遍历为:
2 3 1
中序遍历为:
1 2 3
此时再将右子树视为新的树,重复以上步骤,即可还原整个树。
特别的,当根节点是中序的第一个元素时,即说明中序遍历为:rR,该树没有左子树。
当根节点时中序的最后一个元素时,即说明中序遍历为:Lr,该树没有右子树。
层序遍历树
采用广度优先算法层序遍历树。
将根节点压入队列,开始循环。
当队列不为空时,输出队首元素。若该队首元素有子树,则按照左子树、右子树的顺序将左右节点压入队列。
完成以上步骤后,该节点被遍历结束,弹出队首元素。再次循环。
队列空,层序遍历结束。
代码
#include <iostream>
#include <queue>
using namespace std;
struct node {
int id;
node *left = NULL;
node *right = NULL;
};
int hx[31];
int zx[31];
node *make(int hxl, int hxr, int zxl, int zxr) {
node *p = new node;
p->id = hx[hxr];
int tempi = zxl;
for (; tempi <= zxr; tempi++) {
if (zx[tempi] == hx[hxr]) {
break;
}
}
if (tempi != zxl) {
p->left = make(hxl, hxl + (tempi - zxl - 1), zxl, tempi - 1);
}
if (tempi != zxr) {
p->right = make(hxl + (tempi - zxl), hxr - 1, tempi + 1, zxr);
}
return p;
}
bool nf = false;
void print(node *r) {
queue<node> q;
q.push(*r);
while (!q.empty()) {
if (nf) {
cout << " ";
}
cout << q.front().id;
if (q.front().left != NULL) {
q.push(*q.front().left);
}
if (q.front().right != NULL) {
q.push(*q.front().right);
}
q.pop();
nf = true;
}
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> hx[i];
}
for (int i = 0; i < n; i++) {
cin >> zx[i];
}
int m = 0;
for (m = 0; m < n; m++) {
if (zx[m] == hx[n - 1]) {
break;
}
}
node *r = new node;
r->id = zx[m];
if (m == 0) {
r->left = NULL;
} else {
r->left = make(0, m - 1, 0, m - 1);
}
if (m == n - 1) {
r->right = NULL;
} else {
r->right = make(m, n - 2, m + 1, n - 1);
}
print(r);
}