蓝桥杯试题 算法训练 绘制地图

蓝桥杯试题 算法训练 绘制地图

问题描述

最近,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


#include
#include
#include
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;
}

简单写一下我的想法
①先理解先序遍历是什么:先根后左再右。所以建树的时候也遵循这个顺序
②中序遍历其实就是将树纵向压缩,从左到右结点的位置不变。
比如:
蓝桥杯试题 算法训练 绘制地图_第1张图片

中序遍历就是DBEAFC,直接压缩树就可以了

③中序遍历和先序遍历什么关系:先序遍历的结点会将中序遍历分为两半,其中这个结点的左孩子一定在左半边右孩子一定在右半边
所以递归的时候寻找的范围就可以确定了

你可能感兴趣的:(蓝桥杯)