输入格式:
第一行给出节点的个数N,每个节点的编号为0 ~ N-1
接下来N行每行分别给出:
该节点的编号、该节点的操作数/操作符、该节点的左孩子编号、右孩子编号(-1表示NULL)
输出格式:
第一行输出该表达式树的中缀表达式,该用括号的地方需要用括号括起来。
第二行输出该表达式树的计算结果,保留两位小数。
样例输入:
11
0 - 1 2
1 + 3 4
2 / 5 6
3 4 -1 -1
4 * 7 8
5 6 -1 -1
6 3 -1 -1
7 1 -1 -1
8 - 9 10
9 5 -1 -1
10 2 -1 -1
样例输出:
(4+(1*(5-2)))-(6/3)
分析:显然直接用中序遍历一下树,就可以得到中缀表达式
void inOrder(Node* root){
if(root==NULL) return; printf("(");
if(root->lchild!=NULL) inOrder(root->lchild);
printf("%c",root->data);
if(root->rchild!=NULL) inOrder(root->rchild);
printf(")");
}
但发现问题了,这和样例输出不一样。
仔细分析后发现,当该结点是操作数(即叶子结点)时不需要加括号。
修改后:
1 void inOrder(Node* root){
2 if(root==NULL) return;
3 if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data);
4 else{
5 printf("(");
6 if(root->lchild!=NULL) inOrder(root->lchild);
7 printf("%c",root->data);
8 if(root->rchild!=NULL) inOrder(root->rchild);
9 printf(")");
10 }
11 }
有点像了! 但外层多了一对括号,这是因为根节点也不需要填括号。
所以再次更改,这次引入一个layer变量,记录结点的层数,如果layer>0则需要输出括号。
1 void inOrder(Node* root,int layer){
2 if(root==NULL) return;
3 if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data);
4 else{
5 if(layer>0) printf("(");
6 if(root->lchild!=NULL) inOrder(root->lchild,layer+1);
7 printf("%c",root->data);
8 if(root->rchild!=NULL) inOrder(root->rchild,layer+1);
9 if(layer>0) printf(")");
10 }
11 }
问:如果要计算表达式的值,保留两位小数?
思路:递归解决,每次取两个操作数,和一个操作符运算。
完整代码如下:
1 /**
2 * Copyright(c)
3 * All rights reserved.
4 * Author : Mered1th
5 * Date : 2019-02-23-16.40.52
6 * Description : zhongzhui
7 */
8 #include<cstdio>
9 #include<cstring>
10 #include<iostream>
11 #include<cmath>
12 #include<algorithm>
13 #include<string>
14 #include<unordered_set>
15 #include<map>
16 #include<vector>
17 #include<set>
18 using namespace std;
19 int N;
20 const int maxn=1010;
21 struct Node{
22 char data;
23 Node* lchild;
24 Node* rchild;
25 }nodes[maxn];
26
27 void inOrder(Node* root,int layer){
28 if(root==NULL) return;
29 if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data);
30 else{
31 if(layer>0) printf("(");
32 if(root->lchild!=NULL) inOrder(root->lchild,layer+1);
33 printf("%c",root->data);
34 if(root->rchild!=NULL) inOrder(root->rchild,layer+1);
35 if(layer>0) printf(")");
36 }
37 }
38
39 double calc(double a, double b, char op) {
40 switch (op) {
41 case '+': return a + b;
42 case '-': return a - b;
43 case '*': return a * b;
44 case '/': return a / b;
45 }
46 }
47 double calculateExprTree(Node* root) {
48 if (root == NULL) return 0;
49 if (root->lchild == NULL && root->rchild == NULL) {
50 //叶节点,节点存放的是操作数
51 return root->data - '0';
52 }
53 //非叶结点,节点存放的是操作符
54 double a = calculateExprTree(root->lchild); //递归计算其左子树
55 double b = calculateExprTree(root->rchild); //递归计算其右子树
56 return calc(a, b, root->data); //返回结果
57 }
58
59 int main(){
60 #ifdef ONLINE_JUDGE
61 #else
62 freopen("1.txt", "r", stdin);
63 #endif
64 scanf("%d",&N);
65 getchar();
66 // Node* nodes=new Node[N];
67 int index,l,r;
68 char data;
69 for(int i=0;i<N;i++){
70 scanf("%d %c %d %d",&index,&data,&l,&r);
71 nodes[index].data=data;
72 if(l==-1) nodes[index].lchild=NULL;
73 else nodes[index].lchild=&nodes[l];
74 if(r==-1) nodes[index].rchild=NULL;
75 else nodes[index].rchild=&nodes[r];
76 }
77 Node* root=&nodes[0];
78
79 inOrder(root,0);
80 printf("
");
81 double ans=calculateExprTree(root);
82 printf("%.2f",ans);
83 return 0;
84 }