表达式树的输出与求值


 


 

 

 

输入格式:

第一行给出节点的个数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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM