利用二叉樹求表達式的值,首先要注意表達式中先乘除後加減的運算順序,因此在創建樹的過程當中,就要將加減儘可能做爲根節點,最後一個加減號做爲根節點。建完樹以後是運算過程,採用樹的後序遍從來運算。node
二叉樹的節點結構,其中值的類型用char型算法
struct node { char data; node* left; node* right; };
node *CRTree(char s[],int begin,int end) { node *p; int k,plus=0,posi; if (begin==end) //只有一個字符,構造的是一個葉子節點 { p=(node *)malloc(sizeof(node)); //分配存儲空間 p->data=s[begin]; //值爲s[begin] p->left=NULL; p->right=NULL; return p; } //如下爲begin!=end的狀況 for (k=begin; k<=end; k++) if (s[k]=='+' || s[k]=='-') { plus++; posi=k; //最後一個+或-的位置 } if (plus==0) //沒有+或-的狀況(由於如有+、-,前面必會執行plus++) for (k=begin; k<=end; k++) if (s[k]=='*' || s[k]=='/') { plus++; posi=k; } //以上的處理考慮了優先將+、-放到二叉樹較高的層次上 //因爲未來計算時,運用的是後序遍歷的思路 //處於較低層的乘除會優先運算 //從而體現了「先乘除後加減」的運算法則 //建立一個分支節點,用檢測到的運算符做爲節點值 if (plus!=0) { p=(node *)malloc(sizeof(node)); p->data=s[posi]; //節點值是s[posi] p->left=CRTree(s,begin,posi-1); //左子樹由s[begin]至s[posi-1]構成 p->right=CRTree(s,posi+1,end); //右子樹由s[posi+1]到s[end]構成 return p; } else //若沒有任何運算符,返回NULL return NULL; }
下面是運算過程spa
double Comp(node *b) { double v1,v2; if (b==NULL) return 0; if (b->left==NULL && b->right==NULL) //葉子節點,應該是一個數字字符(本項目未考慮非法表達式) return b->data-'0'; //葉子節點直接返回節點值,結點中保存的數字用的是字符形式,因此要-'0' v1=Comp(b->left); //先計算左子樹 v2=Comp(b->right); //再計算右子樹 switch(b->data) //將左、右子樹運算的結果再進行運算,運用的是後序遍歷的思路 { case '+': return v1+v2; case '-': return v1-v2; case '*': return v1*v2; case '/': if (v2!=0) return v1/v2; else abort(); } }
最後要記得將新建的二叉樹銷燬code
void DestroyBTNode(node *&b) //銷燬二叉樹 { if (b!=NULL) { DestroyBTNode(b->left); DestroyBTNode(b->right); free(b); } }