表达式树的输出与求值

 


 

 

 

输入格式:

第一行给出节点的个数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("\n");
81     double ans=calculateExprTree(root);
82     printf("%.2f",ans);
83     return 0;
84 }

参考:http://blog.csdn.net/liqiutuyuan

猜你喜欢

转载自www.cnblogs.com/Mered1th/p/10423577.html