洛谷P1030已知二叉树的后序遍历和中序遍历,求前序遍历

原题链接
题目描述
前中后序遍历的差别大家都知道,就不再赘述了。
根据后序遍历的特性,我们知道最后一个输出的结点,在题目样例中是A,是这棵二叉树的根节点。再根据中序遍历的特性,在根节点左边输出的结点都是左子树的结点,在根节点右边输出的结点都是右子树的结点。也就是说,B是根节点的左子树的结点,DC是根节点的右子树的结点。递归地,我们容易还原出这棵二叉树。
在这里插入图片描述
在我们判断A是根节点的时候,显然A是前序遍历的第一个输出结点,我们将其输出。递归地,可以得出整个前序遍历的输出顺序。
代码如下:

#include <bits/stdc++.h> 
using namespace std;

const int MAXN = 10;

char pre[MAXN];//前序遍历的顺序
char in[MAXN];//中序遍历的顺序
char past[MAXN];//后序遍历的顺序
int size;//这颗二叉树的结点数
int p=0;//指向目前待更新的pre数组的下标

char last(int l, int r, int*n)//返回中序数组的[l,r]区间中在后序数组中最后出现的结点
{
	for(int i=size-1; i>=0; i--)//从后往前地遍历后序数组
		for(int j=l; j<=r; j++)//遍历中序数组的[l,r]区间
			if(past[i] == in[j]) //如果相等意味着in[j]是[l,r]区间最后一个出现在后序数组中的
			{
				*n = j;//把j结点的下标传回solution函数
				return in[j];
			}
}

void solution(int l, int r) //l和r确定中序数组的一个区间
{
	if(l == r)//如果相等,说明in[l]可以直接放进pre里面
	{
		pre[p++] = in[l];
		return;
	}
	else if(l > r) return;//此时显然不论是in[l]还是in[r]都处理过了,直接返回就行了
	int mid;//用于记录该子树的根节点
	pre[p++] = last(l,r,&mid); //把该子树的根节点写入前序遍历
	solution(l,mid-1);//递归左子树
	solution(mid+1,r);//递归右子树
	//这两个递归调的顺序不可以调换,因为先序遍历一定是先遍历左子树再遍历右子树
}

int main()
{
	scanf("%s %s",in,past);
	size = strlen(in);
	p=0;
	solution(0,size-1);
	for(int cnt=0; cnt<size; cnt++)
		putchar(pre[cnt]);
	putchar('\n');
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值