PAT Advanced 1086

本文介绍了一种将先序和中序遍历序列转换为后序遍历序列的方法,并通过具体的代码实现展示了这一过程。文章提供了几个实例帮助理解算法的工作原理。

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">题意:</span>

给你一颗树,然后按照先序序列压进栈,按照中序序列弹出栈。于是乎,题目的意思转变成给你先序序列和中序序列,你要写出后序序列。

思路:

先序:根 左子树 右子树

中序:左子树 根 右子树

先从先序中找到一个根,然后在中序里面找到他的左,右子树的范围,关于找范围可以先找到左右子树的长度,这样比较方便确定区间。

总结:

=-= 浙大真会出题,卡了我半天,贡献几组数据


5
Push 1
Pop
Push 2
Pop
Push 3
Pop
Push 4
Pop
Push 5
Pop
答案为:5 4 3 2 1

5
Push 1
Push 2
Push 3
Push 4
Push 5
Pop
Pop
Pop
Pop
Pop
答案:5 4 3 2 1
7
Push 1
Push 2
Push 3
Pop
Push 4
Pop
Pop
Pop
Push 5
Push 6
Pop
Push 7
Pop
Pop
答案:4 3 2 7 6 5 1

code:

#include<iostream>
#include<string>
#include<stack>
using namespace std;
#define maxn 150
int N;
int pushorder[maxn];
struct node
{
	int left, right;
};
node tree[maxn];
int preorder[maxn];
int inorder[maxn];
int postorder[maxn];
int root = 0;
int ans = 0;
int build(int be,int pos)
{
	if (pos - be == 1)
	{
		return inorder[be];
	}
	for (int i = be; i < pos; i++)
	{
		if (preorder[root] == inorder[i])
		{
			int temp = preorder[root];
			int L = i - be;
			int R = pos - i - 1;
			root++;
			tree[temp].left = build(i-L, i);
			if (tree[temp].left)
				root++;
			tree[temp].right = build(i + 1, pos);
			if (!tree[temp].right)
				root--;
			return temp;
		}
	}
	return 0;
}

void Postorder(int root)
{
	if (tree[root].left + tree[root].right == 0)
	{
		postorder[ans++] = root;
		return;
	}
	if (tree[root].left)
		Postorder(tree[root].left);
	if (tree[root].right)
		Postorder(tree[root].right);
	postorder[ans++] = root;
}
void input()
{
	int pre, in;
	pre = in = 0;
	string stemp;
	stack<int>s;
	int node;
	for (int i = 1; i <= 2 * N; i++)
	{
		
		cin >> stemp;
		if (stemp == "Push")
		{
			cin >> node;
			s.push(node);
			preorder[pre++] = node;
		}
		else
		{
			inorder[in++] = s.top();
			s.pop();
		}
	}
	build(0,N);
	Postorder(preorder[0]);
	cout << postorder[0];
	for (int i = 1; i < ans; i++)
		cout << " " << postorder[i];
}
int main()
{
	cin >> N;
	input();
	return 0;
}

这里总结下,我写的时候犯的错误。

1.root的值虽说是随着递归增加的,但是有可能由于左子树没有值,这时候转向右子树的时候root值不能随便增加

2.还是root值的问题,当这时候已经转向右子树,但是右子树是空的,而此时root值已经增加,所以当右子树返回根节点的时候需要加个判断,有值root才不自减,无值root自减。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值