蓝桥杯试题 算法训练 绘制地图
问题描述
最近,WYF正准备参观他的点卡工厂。WYF集团的经理氰垃圾需要帮助WYF设计参“观”路线。现在,氰垃圾知道一下几件事情:
1.WYF的点卡工厂构成一颗二叉树。
2.一共有n座工厂。
3.他需要把这颗树上的点以后序遍历的方法列出来,才能绘制地图。
还好,最近他的属下给了他先序遍历和中序遍历的数据。可是,氰垃圾最近还要帮㊎澤穻解决一些问题,没有时间。请你帮帮他,替他完成这项任务。由于氰垃圾的一些特殊的要求,WYF的参观路线将会是这棵树的后序遍历。
输入格式
第一行一个整数n,表示一共又n座工厂。
第二行n个整数,表示先序遍历。
第三行n个整数,表示中序遍历。
输出格式
输出共一行,包含n个整数,为后序遍历。
样例输入
8
1 2 4 5 7 3 6 8
4 2 7 5 1 8 6 3
样例输出
4 7 5 2 8 6 3 1
数据规模和约定
0<n<100000,。保证先序遍历和中序遍历合法,且均为1~n。
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
int N;
typedef struct BiTNode
{
int thisNode;
BiTNode* leftNode, * rightNode; //左结点,右结点
}BiTNode, * BiTree;
BiTree createTree(int* P, int* M, int start, int end, int n) {
BiTree T = NULL;
int s = start, e = end;
if (N == n) return T; //N==n说明已经建树完毕
int i;
for (i = start; i < end; i++) {
if (M[i] == P[N]) break; //在中序遍历中找到先序遍历对应的结点
}
if (i == end) return T; //i == end说明没找到就返回
else
{
T = (BiTree)malloc(sizeof(BiTNode));
if (!T); //判断是否建树成功
T->thisNode = P[N];
N++; //继续下一个结点
T->leftNode = createTree(P, M, s, i, n); //在s和i中找左节点,找不到就返回空
T->rightNode = createTree(P, M, i + 1, e, n);//在i+1和e中找右节点,找不到就返回空
}
return T;
}
void visited(BiTree T) {
cout << T->thisNode << " ";
}
void PostorderTraversal(BiTree T) {
if (T == NULL) return;
PostorderTraversal(T->leftNode);
PostorderTraversal(T->rightNode);
visited(T);
}
int main() {
int n;
cin >> n;
int P[100000], M[100000];
memset(P, 0, sizeof(int) * 100000);
memset(M, 0, sizeof(int) * 100000);
for (int i = 0; i < n; i++) {
cin >> P[i];
}
for (int i = 0; i < n; i++) {
cin >> M[i];
}
N = 0;
BiTree T = createTree(P, M, 0, n , n);
PostorderTraversal(T);
return 0;
}
简单写一下我的想法
①先理解先序遍历是什么:先根后左再右。所以建树的时候也遵循这个顺序
②中序遍历其实就是将树纵向压缩,从左到右结点的位置不变。
比如:
中序遍历就是DBEAFC,直接压缩树就可以了
③中序遍历和先序遍历什么关系:先序遍历的结点会将中序遍历分为两半,其中这个结点的左孩子一定在左半边,右孩子一定在右半边。
所以递归的时候寻找的范围就可以确定了