You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 30;
/*
思路
1、数据处理,通过记录入度找到入度为0的点找到根节点
2、二元运算必须有符号右边那个式子即根据数据构建完树后的右孩子
故在递归遍历树的时候,只要判断该节点是否有孩子,
然后返回的字符串数: 递归左子树的string值 + 该节点的string值 + 递归右子树的string值
3、如果该节点不是根节点,则在该返回值的左右两边加上括号
4、最后输出返回值
黄海总结:
1、乍一看此题感觉无从下手因为不知道每个点都是什么节点号后来慢慢从测试用例1中发现
data 都是什么 *,a,b,-,c之类不是节点号应该是具体的操作符也就是值。
那节点号在哪里呢再看一下后面的left_child,right_child,发现是
8 7
-1 -1
4 1
2 5
这个来理解一下应该是指8号节点7号节点-1代表的是NULL节点也就是到头了是叶子。
再来仔细看一下发现出现的数字是1 2 4 5 6 7 8,单单缺少了一个3
为啥缺少3呢
因为3不是任何人的left_child,right_child,它是根!!!!,这样的话,整个图就完整了!
*/
int n;
string w[N];
int l[N], r[N], in[N];
int isleaf[N];
/*
8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1
(a+b)*(c*(-d))
*/
string dfs(int u) {
// 表达式树特点:叶子节点都是真实数字,非叶子节点都是操作符
string left, right;
// if (isleaf[u]) return w[u]; // 递归终点,如果是叶子,本句话可以省略掉
// 这是因为isleaf[u]时,l[u]==-1 && r[u]==-1 ,则下面的两个分支都不会走直接到了return那句left,right都是空还是返回w[u],一样的
if (l[u] != -1) {
left = dfs(l[u]); // 递归左儿子,
if (!isleaf[l[u]]) left = "(" + left + ")"; // 如果左儿子不是叶子,需要把表达式加上括号
}
if (r[u] != -1) { // 右儿子不为空
right = dfs(r[u]); // 递归右儿子
if (!isleaf[r[u]]) right = "(" + right + ")"; // 如果右儿子不是叶子,需要把表达式加上括号
}
// 返回中序遍历结果
return left + w[u] + right;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> l[i] >> r[i]; // data left_child right_child
if (l[i] != -1) in[l[i]]++; // 记录入度
if (r[i] != -1) in[r[i]]++; // 记录入度
if (l[i] == -1 && r[i] == -1) isleaf[i] = 1; // 叶子
}
// 找根
int root;
for (root = 1; root <= n; root++)
if (!in[root]) break; // 入度为零的是根
// 通过中序遍历,构建中缀表达式
cout << dfs(root) << endl;
return 0;
}