PAT 甲级 1020 Tree Traversals
给定二叉树的后序和中序遍历,输出二叉树的层序遍历(二叉树每个节点的值不同)
用index记录树中每个节点所在的位置,从0开始
用map记录节点信息,index为key,这样map自动从0开始排序,只需迭代输出map存储的值即可完成层序遍历
后序遍历的最后一个节点是子树的根节点,通过根节点的值,可在中序遍历中把子树分为左子树和右子树
后序遍历中左子树的根节点位置为root-(end - i + 1),即根节点位置-(右子树节点个数 + 1)
后序遍历中右子树的根节点位置为 root - 1,即根节点位置 - 1
i是中序遍历中根节点位置,end是中序遍历中最后一个元素位置
所以end - i为右子树节点个数
// 1020 Tree Traversals.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <vector>
#include <map>
using namespace std;
vector<int> post, 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] != post[root]) i++;
m[index] = post[root];
pre(root - end + i - 1, start, i - 1, 2 * index + 1);
pre(root - 1, i + 1, end, 2 * index + 2);
}
int main()
{
int n;
cin >> n;
post.resize(n);
in.resize(n);
for (int i = 0; i < n; i++) cin >> post[i];
for (int i = 0; i < n; i++) cin >> in[i];
pre(n - 1, 0, n - 1, 0);
auto it = m.begin();
cout << it->second;
while (++it != m.end()) cout << " " << it->second;
return 0;
}
resize和reserve
esize(),设置大小(size);
reserve(),设置容量(capacity);
size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。
打个比方:正在建造的一辆公交车,车里面可以设置40个座椅(reserve(40);),这是它的容量,但并不是说它里面就有了40个座椅,只能说明这部车内部空间大小可以放得下40张座椅而已。而车里面安装了40个座椅(resize(40)😉,这个时候车里面才真正有了40个座椅,这些座椅就可以使用了。
已知后序中序输出前序
和本题的思路一模一样,只是不需要记录index,当找到根节点时直接输出,然后分别输出左子树的前序遍历和右子树的前序遍历
#include <cstdio>
using namespace std;
int post[] = {3, 4, 2, 6, 5, 1};
int in[] = {3, 2, 4, 1, 6, 5};
void pre(int root, int start, int end) {
if(start > end) return ;
int i = start;
while(i < end && in[i] != post[root]) i++;
printf("%d ", post[root]);
pre(root - 1 - end + i, start, i - 1);
pre(root - 1, i + 1, end);
}
int main() {
pre(5, 0, 5);
return 0;
}