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 100
void 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;
else
return LESS_THAN;
}
else if (x == '*' || x == '/') {
if (y == '+' || y == '-' || y == '*' || y == '/' || y == ')' || y == '#')
return GREATER_THAN;
else
return LESS_THAN;
}
else if (x == '(') {
if (y == ')')
return EQUAL;
else
return LESS_THAN;
}
else if (x == ')')
return GREATER_THAN;
else {
if (y == '#')
return EQUAL;
else
return 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 100
void 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;
else
return LESS_THAN;
}
else if (x == '*' || x == '/') {
if (y == '+' || y == '-' || y == '*' || y == '/' || y == ')' || y == '#')
return GREATER_THAN;
else
return LESS_THAN;
}
else if (x == '(') {
if (y == ')')
return EQUAL;
else
return LESS_THAN;
}
else if (x == ')')
return GREATER_THAN;
else {
if (y == '#')
return EQUAL;
else
return 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;
}