表達式樹的輸出與求值

 


 

 

 

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

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

相關文章
相關標籤/搜索