
輸入格式:
第一行給出節點的個數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 }
