'commit'
This commit is contained in:
88
TangDou/CSP-J/J2_2020/ZhuanTi_BiaoDaShi/1623.cpp
Normal file
88
TangDou/CSP-J/J2_2020/ZhuanTi_BiaoDaShi/1623.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user