輸入格式: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 }