复习一下基础数据结构,这是以前没有搞明白的题目,现在搞明白了,建议画图理解
题目链接:PAT A1020
规律
① 后续序列中最后一个是根节点
② 中序序列中根节点左边是左子树,右边是右子树
所以:
- 找到中序序列中的根节点位置
- 然后将新树的范围划定出来:
① 中序左子树为根节点左边
② 右子树为根节点右边;
③ 后序序列左子树为左边的n个(n为中序左子树数目)
④ 后序右子树为剩下的部分(不包含最后一个根节点) - 递归地创建左子树和右子树
代码
#include <bits/stdc++.h>
#define MAX 50
using namespace std;
int n;
//后续序列
int post_order[MAX];
//中序序列
int in_order[MAX];
struct tree {
int data;
tree *left;
tree *right;
};
//找到中序序列中的根节点位置
int findRoot(int root, int left, int right) {
for (int i = left; i <= right; ++i) {
if (root == in_order[i])
return i;
}
}
//范围全部为闭区间
//pl:后续序列开始(post_order left)
//pr:后续序列结束(post_order right)
//il:中续序列结束(in_order right)
//ir:中续序列结束(in_order right)
tree *create(int pl, int pr, int il, int ir) {
if (pl > pr || il > ir) {
return nullptr;
}
int root = post_order[pr];
int rootPos = findRoot(root, il, ir);
tree *t = new tree({root, nullptr, nullptr});
int count = rootPos - il;
//划定左子树范围
t->left = create(pl, pl + count - 1, il, rootPos - 1);
//划定右子树范围
t->right = create(pl + count, pr - 1, rootPos + 1, ir);
return t;
}
//层序遍历
void levelTraversal(tree *root) {
bool flag = true;
queue<tree *> que;
que.push(root);
while (!que.empty()) {
tree *node = que.front();
que.pop();
if (node->left)que.push(node->left);
if (node->right)que.push(node->right);
if (flag) {
cout << node->data;
flag = false;
} else {
cout << " " << node->data;
}
}
}
//PAT 1020:Tree Traversals
int main() {
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> post_order[i];
}
for (int i = 0; i < n; ++i) {
cin >> in_order[i];
}
tree *root = create(0, n - 1, 0, n - 1);
levelTraversal(root);
return 0;
}