題目
表達式(a-(b+c))*(d/e)存儲在如下圖所示的一棵以二叉鏈表爲存儲結構的二叉樹中(二叉樹結點的data域爲字符型),編寫程序求出該表達式的值(表達式中的操作數都是一位的整數)。
分析
左子樹爲表達式A,右子樹爲表達式B,經過分析可以得:先求左子樹所表示的表達式的值,然後求右子樹所表示的表達式的值,最後將兩個結果相乘就是整個表達式的數值。即先遍歷左子樹(得左子樹的值),再遍歷右子樹(得右子樹的值),最後訪問根(得運算符)的二叉樹的後序遍歷方式。
代碼
核心代碼:
/* 求表達式的值 */
/* 例:*-9##+3##2##/4##2## */
int comp(BTNode *p) {
int A,B;
if(p!=NULL) {
if(p->lchild!=NULL&&p->rchild!=NULL) { // 如果當前結點的左子樹和右子樹非空,則爲表達式,再用後序遍歷求值 */
A=comp(p->lchild);// 後序遍歷求出左子樹的值,賦值給A
B=comp(p->rchild);// 後序遍歷求出右子樹的值,賦值給B
return op(A,B,p->data);// 根據已求得的A與B和當前結點的運算符求出整個表達式的值
} else { // 如果當前結點的左右子樹都爲空,則爲數值,直接返回,p->data-'0'是將字符型數字轉化爲整型數字
return p->data-'0';
}
} else { // 如果是空樹,則表達式的值爲0
return 0;
}
}
完整代碼:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
/* 數結構體類型定義*/
typedef struct BTNode {
char data;// 這裏默認結點data域爲char類型
struct BTNode *lchild;// 左孩子指針域
struct BTNode *rchild;// 右孩子指針域
} BTNode,*BiTree;
/* 根據輸入創建二叉樹 */
/* 例:ABC##DE##F##GH### */
void CreatBiNode(BTNode **Node) { //此處應注意傳遞的參數(二重指針)
char data;
scanf("%c", &data);
*Node = (BiTree)malloc(sizeof(BTNode));
if (data == '#') {
*Node = NULL;
} else if ((data != '#') && (*Node)) {
(*Node)->data = data;
(*Node)->lchild = NULL;
(*Node)->rchild = NULL;
CreatBiNode(&(*Node)->lchild);
CreatBiNode(&(*Node)->rchild);
}
}
int op(int A,int B,char p) {
if(p=='+') {
return A+B;
} else if(p=='-') {
return A-B;
} else if(p=='*') {
return A*B;
} else if(p=='/') {
return A/B;
}
}
/* 求表達式的值 */
/* 例:*-9##+3##2##/4##2## */
int comp(BTNode *p) {
int A,B;
if(p!=NULL) {
if(p->lchild!=NULL&&p->rchild!=NULL) { // 如果當前結點的左子樹和右子樹非空,則爲表達式,再用後序遍歷求值 */
A=comp(p->lchild);// 後序遍歷求出左子樹的值,賦值給A
B=comp(p->rchild);// 後序遍歷求出右子樹的值,賦值給B
return op(A,B,p->data);// 根據已求得的A與B和當前結點的運算符求出整個表達式的值
} else { // 如果當前結點的左右子樹都爲空,則爲數值,直接返回,p->data-'0'是將字符型數字轉化爲整型數字
return p->data-'0';
}
} else { // 如果是空樹,則表達式的值爲0
return 0;
}
}
int main() {
printf("先序輸入二叉樹(空結點用'#'表示):");
BiTree T=NULL;
CreatBiNode(&T);// 創建二叉樹
/* 求表達式的值 */
int r=comp(T);
printf("%d",r);
return 0;
}
以下面題爲測試例: