【题解】【AcWing】1576. 再次树遍历

79 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1576. 再次树遍历

原题传送:AcWing 1576. 再次树遍历

通过使用栈可以以非递归方式实现二叉树的中序遍历。

例如,假设遍历一个如下图所示的 66 节点的二叉树(节点编号从 1166 )。

则堆栈操作为:push(1);push(2);push(3);pop();pop();push(4);pop();pop();push(5);push(6);pop();pop()。

我们可以从此操作序列中生成唯一的二叉树。

你的任务是给出这棵树的后序遍历。

输入格式

第一行包含整数 NN ,表示树中节点个数。

树中节点编号从 11NN

接下来 2N2N 行,每行包含一个栈操作,格式为:

  • Push X,将编号为 XX 的节点压入栈中。
  • Pop,弹出栈顶元素。

输出格式

输出这个二叉树的后序遍历序列。

数据保证有解,数和数之间用空格隔开,末尾不能有多余空格。

数据范围

1N301 \le N \le 30

输入样例:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

输出样例:

3 4 2 6 5 1

思路一:

Push为前序遍历,Pop为中序遍历,构造一棵树并保存后序遍历的序列。

题解一:

#include<bits/stdc++.h>

using namespace std;

const int N = 40;

int n, k1 = 0, k2 = 0;
stack<int> s;
int in[N], pre[N];
int post[N], cnt;
unordered_map<int, int> l, r, pos;

int build(int il, int ir, int pl, int pr)
{
	int root = pre[pl];
	int k = pos[root];
	if(il < k)
		l[root] = build(il, k - 1, pl + 1, pl + 1 + (k - 1 - il));
	if(k < ir)
		r[root] = build(k + 1, ir, pl + 1 + (k - 1 - il) + 1, pr);
		
	post[cnt++] = root;
	return root;
}

int main()
{	
	cin >> n;
	for(int i = 0; i < n * 2; i++)
	{
		string t;
		cin >> t;
		if(t == "Push")
		{
			int num;
			cin >> num;
			s.push(num);
			pre[k1++] = num;
		}
		else
		{
			int top = s.top();
			in[k2] = top;
			pos[in[k2]] = k2;
			k2++;
			s.pop();
		}
	}
	
	build(0, n - 1, 0, n - 1);
	
	cout << post[0];
	for(int i = 1; i < n; i++)
		cout << " " << post[i];
	cout << endl;
	
	return 0;
}

思路二:

对于所有的 Push ,除第一个Push是根结点,如果上一个是 Push ,说明当前这个点是上一个点的左儿子。如果上一个是 Pop ,说明当前这个点是上一个点的右儿子。

题解二:

#include<bits/stdc++.h>

using namespace std;

const int N = 40;

int n;
int l[N], r[N];

void dfs(int u, int root)
{
	if(!u)
		return;
	
	dfs(l[u], root);
	dfs(r[u], root);
	
	cout << u;
	if(u != root)
		cout << " ";
}

int main()
{	
	cin >> n;
	
	int root, last = 0, type;
	stack<int> stk;
	for(int i = 0; i < n * 2; i++)
	{
		string t;
		cin >> t;
		if(t == "Push")
		{
			int x;
			cin >> x;
			if(!last)
				root = x;
			else
			{
				if(type == 0)
					l[last] = x;
				else
					r[last] = x;
			}
			stk.push(x);
			last = x;
			type = 0;
		}
		else
		{
			last = stk.top();
			stk.pop();
			type = 1;
		}
	}
	
	dfs(root, root);
	
	return 0;
}