输入格式:node
第一行给出节点的个数N,每一个节点的编号为0 ~ N-1
接下来N行每行分别给出:
该节点的编号、该节点的操做数/操做符、该节点的左孩子编号、右孩子编号(-1表示NULL)ios
输出格式:ui
第一行输出该表达式树的中缀表达式,该用括号的地方须要用括号括起来。
第二行输出该表达式树的计算结果,保留两位小数。spa
样例输入:.net
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 -1code
样例输出:
(4+(1*(5-2)))-(6/3)blog
分析:显然直接用中序遍历一下树,就能够获得中缀表达式递归
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(")"); }
但发现问题了,这和样例输出不同。 ip
仔细分析后发现,当该结点是操做数(即叶子结点)时不须要加括号。 get
修改后:
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 }