5.8 案例分析与实现
利用二叉树求解表达式的值
表达式树的创建
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{char data;struct BiTNode* lchild;struct BiTNode* rchild;
}BiTNode, * BiTree;
typedef struct OPTRSNode
{char Operator;struct OPTRSNode* next;
}OPTRSNode,*OPTRLStack;
typedef struct EXPTSNode
{BiTree Tree;struct EXPTSNode* next;
}EXPTSNode, * EXPTLStack;
typedef enum {GREATER_THAN = '>',LESS_THAN = '<',EQUAL = '=',ERROR
} Pre;#define MAXSIZE 100void InitOPTRLStack(OPTRLStack& OPTR);
void PushOPTRLStack(OPTRLStack& OPTR, char e);
void PopOPTRLStack(OPTRLStack& OPTR, char& e);
char GettopOPTRLStack(OPTRLStack& OPTR);
void InitEXPTLStack(EXPTLStack& EXPT);
void PushEXPTLStack(EXPTLStack& EXPT, BiTree e);
void PopEXPTLStack(EXPTLStack& EXPT, BiTree& e);
BiTree GettopEXPTLStack(EXPTLStack& EXPT);
void CreateExpTree(BiTree& T, BiTree a, BiTree b, char x);
int In(char ch);
Pre Precede(char x, char y);
void InitExpTree(EXPTLStack& EXPT, char* s);
int getline(char* s, int limit);
void PreOrderTraverse(BiTree& T);
void InOrderTraverse(BiTree& T);
void PosOrderTraverse(BiTree& T);
void FreeTree(BiTree& T);
int main()
{int length = 0;int num = 1;char s[MAXSIZE];EXPTLStack EXPT = NULL;OPTRLStack OPTR = NULL;BiTree T = NULL;char choice = '\0';while (1){printf("请输入第%d个表达式:", num);length = getline(s, MAXSIZE);InitExpTree(EXPT, s);T = GettopEXPTLStack(EXPT);printf("该表达式树的先序序列为:");PreOrderTraverse(T);printf("\n该表达式树的中序序列为:");InOrderTraverse(T);printf("\n该表达式树的后序序列为:");PosOrderTraverse(T);FreeTree(T);printf("\n是否继续?(y/n)");scanf_s(" %c", &choice);getchar();if (choice != 'y' && choice != 'Y'){break;}num++;printf("\n\n");}return 0;
}
void InitOPTRLStack(OPTRLStack& OPTR)
{OPTR = NULL;
}
void PushOPTRLStack(OPTRLStack& OPTR, char e)
{OPTRSNode* p = (OPTRSNode*)malloc(sizeof(OPTRSNode));if (!p){printf("操作符入栈时,内存分配失败。\n");return;}p->Operator = e;p->next = OPTR;OPTR = p;
}
void PopOPTRLStack(OPTRLStack& OPTR, char& e)
{if (!OPTR){printf("操作符出栈时,栈不存在。\n");return;}OPTRSNode* p = OPTR;e = p->Operator;OPTR = OPTR->next;free(p);
}
char GettopOPTRLStack(OPTRLStack& OPTR)
{if (!OPTR){printf("取栈顶操作符时,栈不存在。\n");return '\0';}return OPTR->Operator;
}
void InitEXPTLStack(EXPTLStack& EXPT)
{EXPT = NULL;
}
void PushEXPTLStack(EXPTLStack& EXPT, BiTree e)
{EXPTSNode* p = (EXPTSNode*)malloc(sizeof(EXPTSNode));if (!p){printf("表达树入栈时,内存分配失败。\n");return;}p->Tree = e;p->next = EXPT;EXPT = p;
}
void PopEXPTLStack(EXPTLStack& EXPT, BiTree& e)
{if (!EXPT){printf("表达树出栈时,栈不存在。\n");return;}EXPTSNode* p = EXPT;e = p->Tree;EXPT = EXPT->next;free(p);
}
BiTree GettopEXPTLStack(EXPTLStack& EXPT)
{if (!EXPT){printf("取表达树栈栈顶时,栈不存在。\n");return NULL;}return EXPT->Tree;
}
void CreateExpTree(BiTree& T, BiTree a, BiTree b, char x)
{T = (BiTree)malloc(sizeof(BiTNode));T->data = x;T->lchild = a;T->rchild = b;
}
int In(char ch)
{if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')'|| ch == '#'){return 1;}else{return 0;}
}
Pre Precede(char x, char y)
{if ((x == '(' && y == '#') || (x == ')' && y == '(') || (x == '#' && y == ')')){return ERROR; }else if (x == '+' || x == '-') {if (y == '+' || y == '-' || y == ')' || y == '#')return GREATER_THAN;elsereturn LESS_THAN;}else if (x == '*' || x == '/') {if (y == '+' || y == '-' || y == '*' || y == '/' || y == ')' || y == '#')return GREATER_THAN;elsereturn LESS_THAN;}else if (x == '(') {if (y == ')')return EQUAL;elsereturn LESS_THAN;}else if (x == ')')return GREATER_THAN;else {if (y == '#')return EQUAL;elsereturn LESS_THAN;}
}
void InitExpTree(EXPTLStack& EXPT, char *s)
{InitEXPTLStack(EXPT);OPTRLStack OPTR = NULL;InitOPTRLStack(OPTR);int i = 0;char ch = s[i];BiTree T = NULL;char theta = '\0';char x = '\0';BiTree a = NULL;BiTree b = NULL;PushOPTRLStack(OPTR, '#');while (ch != '#' || GettopOPTRLStack(OPTR) != '#'){if(!In(ch)){CreateExpTree(T, NULL, NULL, ch);PushEXPTLStack(EXPT, T);++i;ch = s[i]; }else{switch (Precede(GettopOPTRLStack(OPTR), ch)){case LESS_THAN:PushOPTRLStack(OPTR, ch);++i;ch = s[i]; break;case GREATER_THAN:PopOPTRLStack(OPTR, theta);PopEXPTLStack(EXPT, b);PopEXPTLStack(EXPT, a);CreateExpTree(T, a, b, theta);PushEXPTLStack(EXPT, T);break;case EQUAL:PopOPTRLStack(OPTR, x);++i;ch = s[i]; break;}}}while (OPTR) {PopOPTRLStack(OPTR, x);}
}int getline(char* s, int limit)
{int c = 0;int i = 0;for (i = 0; i < limit - 1 && (c = getchar()) != EOF && c != '\n'; i++){s[i] = c;}s[i] = '\0';return i;
}
void PreOrderTraverse(BiTree& T)
{if (T){printf("%c", T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}
}
void InOrderTraverse(BiTree& T)
{if (T){InOrderTraverse(T->lchild);printf("%c", T->data);InOrderTraverse(T->rchild);}
}
void PosOrderTraverse(BiTree& T)
{if (T){PosOrderTraverse(T->lchild);PosOrderTraverse(T->rchild);printf("%c", T->data);}
}
void FreeTree(BiTree& T)
{if (T) {FreeTree(T->lchild);FreeTree(T->rchild);free(T);T = NULL;}
}
表达式树的求值
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{char data;struct BiTNode* lchild;struct BiTNode* rchild;
}BiTNode, * BiTree;
typedef struct OPTRSNode
{char Operator;struct OPTRSNode* next;
}OPTRSNode, * OPTRLStack;
typedef struct EXPTSNode
{BiTree Tree;struct EXPTSNode* next;
}EXPTSNode, * EXPTLStack;
typedef enum {GREATER_THAN = '>',LESS_THAN = '<',EQUAL = '=',ERROR
} Pre;#define MAXSIZE 100void InitOPTRLStack(OPTRLStack& OPTR);
void PushOPTRLStack(OPTRLStack& OPTR, char e);
void PopOPTRLStack(OPTRLStack& OPTR, char& e);
char GettopOPTRLStack(OPTRLStack& OPTR);
void InitEXPTLStack(EXPTLStack& EXPT);
void PushEXPTLStack(EXPTLStack& EXPT, BiTree e);
void PopEXPTLStack(EXPTLStack& EXPT, BiTree& e);
BiTree GettopEXPTLStack(EXPTLStack& EXPT);
void CreateExpTree(BiTree& T, BiTree a, BiTree b, char x);
int In(char ch);
Pre Precede(char x, char y);
void InitExpTree(EXPTLStack& EXPT, char* s);
int getline(char* s, int limit);
void PreOrderTraverse(BiTree& T);
void InOrderTraverse(BiTree& T);
void PosOrderTraverse(BiTree& T);
void FreeTree(BiTree& T);
int Operate(int a, char x, int b);
int EvaluateExpTree(BiTree T);int main()
{int length = 0;int num = 1;char s[MAXSIZE];EXPTLStack EXPT = NULL;OPTRLStack OPTR = NULL;BiTree T = NULL;int result = 0;char choice = '\0';while (1){printf("请输入第%d个表达式:", num);length = getline(s, MAXSIZE);InitExpTree(EXPT, s);T = GettopEXPTLStack(EXPT);printf("该表达式树的先序序列为:");PreOrderTraverse(T);printf("\n该表达式树的中序序列为:");InOrderTraverse(T);printf("\n该表达式树的后序序列为:");PosOrderTraverse(T);result = EvaluateExpTree(T);printf("\n该表达式的计算结果为:%d", result);FreeTree(T);printf("\n是否继续?(y/n)");scanf_s(" %c", &choice);getchar();if (choice != 'y' && choice != 'Y'){break;}num++;printf("\n\n");}return 0;
}
void InitOPTRLStack(OPTRLStack& OPTR)
{OPTR = NULL;
}
void PushOPTRLStack(OPTRLStack& OPTR, char e)
{OPTRSNode* p = (OPTRSNode*)malloc(sizeof(OPTRSNode));if (!p){printf("操作符入栈时,内存分配失败。\n");return;}p->Operator = e;p->next = OPTR;OPTR = p;
}
void PopOPTRLStack(OPTRLStack& OPTR, char& e)
{if (!OPTR){printf("操作符出栈时,栈不存在。\n");return;}OPTRSNode* p = OPTR;e = p->Operator;OPTR = OPTR->next;free(p);
}
char GettopOPTRLStack(OPTRLStack& OPTR)
{if (!OPTR){printf("取栈顶操作符时,栈不存在。\n");return '\0';}return OPTR->Operator;
}
void InitEXPTLStack(EXPTLStack& EXPT)
{EXPT = NULL;
}
void PushEXPTLStack(EXPTLStack& EXPT, BiTree e)
{EXPTSNode* p = (EXPTSNode*)malloc(sizeof(EXPTSNode));if (!p){printf("表达树入栈时,内存分配失败。\n");return;}p->Tree = e;p->next = EXPT;EXPT = p;
}
void PopEXPTLStack(EXPTLStack& EXPT, BiTree& e)
{if (!EXPT){printf("表达树出栈时,栈不存在。\n");return;}EXPTSNode* p = EXPT;e = p->Tree;EXPT = EXPT->next;free(p);
}
BiTree GettopEXPTLStack(EXPTLStack& EXPT)
{if (!EXPT){printf("取表达树栈栈顶时,栈不存在。\n");return NULL;}return EXPT->Tree;
}
void CreateExpTree(BiTree& T, BiTree a, BiTree b, char x)
{T = (BiTree)malloc(sizeof(BiTNode));T->data = x;T->lchild = a;T->rchild = b;
}
int In(char ch)
{if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#'){return 1;}else{return 0;}
}
Pre Precede(char x, char y)
{if ((x == '(' && y == '#') || (x == ')' && y == '(') || (x == '#' && y == ')')){return ERROR; }else if (x == '+' || x == '-') {if (y == '+' || y == '-' || y == ')' || y == '#')return GREATER_THAN;elsereturn LESS_THAN;}else if (x == '*' || x == '/') {if (y == '+' || y == '-' || y == '*' || y == '/' || y == ')' || y == '#')return GREATER_THAN;elsereturn LESS_THAN;}else if (x == '(') {if (y == ')')return EQUAL;elsereturn LESS_THAN;}else if (x == ')')return GREATER_THAN;else {if (y == '#')return EQUAL;elsereturn LESS_THAN;}
}
void InitExpTree(EXPTLStack& EXPT, char* s)
{InitEXPTLStack(EXPT);OPTRLStack OPTR = NULL;InitOPTRLStack(OPTR);int i = 0;char ch = s[i];BiTree T = NULL;char theta = '\0';char x = '\0';BiTree a = NULL;BiTree b = NULL;PushOPTRLStack(OPTR, '#');while (ch != '#' || GettopOPTRLStack(OPTR) != '#'){if (!In(ch)){CreateExpTree(T, NULL, NULL, ch);PushEXPTLStack(EXPT, T);++i;ch = s[i]; }else{switch (Precede(GettopOPTRLStack(OPTR), ch)){case LESS_THAN:PushOPTRLStack(OPTR, ch);++i;ch = s[i]; break;case GREATER_THAN:PopOPTRLStack(OPTR, theta);PopEXPTLStack(EXPT, b);PopEXPTLStack(EXPT, a);CreateExpTree(T, a, b, theta);PushEXPTLStack(EXPT, T);break;case EQUAL:PopOPTRLStack(OPTR, x);++i;ch = s[i]; break;}}}while (OPTR){PopOPTRLStack(OPTR, x);}
}int getline(char* s, int limit)
{int c = 0;int i = 0;for (i = 0; i < limit - 1 && (c = getchar()) != EOF && c != '\n'; i++){s[i] = c;}s[i] = '\0';return i;
}
void PreOrderTraverse(BiTree& T)
{if (T){printf("%c ", T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}
}
void InOrderTraverse(BiTree& T)
{if (T){InOrderTraverse(T->lchild);printf("%c ", T->data);InOrderTraverse(T->rchild);}
}
void PosOrderTraverse(BiTree& T)
{if (T){PosOrderTraverse(T->lchild);PosOrderTraverse(T->rchild);printf("%c ", T->data);}
}
void FreeTree(BiTree& T)
{if (T){FreeTree(T->lchild);FreeTree(T->rchild);free(T);T = NULL;}
}
int Operate(int a, char x, int b)
{int result = '0'; if (x == '+'){result = a + b ;}else if (x == '-'){result = a - b;}else if (x == '*'){result = a * b;}else{if (b != 0){result = a / b;}else{printf("除数不能为0");return -184656324;}}return result;
}int EvaluateExpTree(BiTree T)
{int lvalue = 0;int rvalue = 0;int result = 0;if (T->lchild == NULL && T->rchild == NULL){result = T->data - '0';}else{lvalue = EvaluateExpTree(T->lchild);rvalue = EvaluateExpTree(T->rchild);result = Operate(lvalue, T->data, rvalue);}return result;
}