使用二叉树实现一位的加减乘除运算(系统输入#结束):
#include
#include
#include
#define MaxS 20
//结构体部分
typedef struct node{
char val;/*数据域*/
struct node* rc;
struct node* lc;
}Node;
typedef struct bt{
Node* root;
}BT;
//函数声明部分
void Init(BT *a,char s[]); /*初始化二叉树和字符串*/
void Read(char s[]); /*读取表达式*/
void BuildBT(BT *a,char *s); /*构建二叉树*/
float Cal(BT *a); /*计算二叉树*/
void CLR(Node *a); /*清空树*/
Node* MFS(Node* n); /*中序遍历*/
void push(BT *a,char* s,int ic);
int getIndex(char theta) ;
char getPriority(char theta1, char theta2);
//函数定义部分
void Init(BT *a,char s[]){
// printf("\n进入函数:Init\n");
for(int i=0;iroot=NULL;
// printf("\n函数结束:Init\n");
}
void CLR(Node* a){ //后序遍历清空树
if(a->lc){
CLR(a->lc);
}
if(a->rc){
CLR(a->rc);
}
free(a);
}
void Read(char s[]){ /*读取表达式*/
// printf("\n进入函数:Read\n");
printf("请输入表达式:");
for(int i=0;irc==NULL){
pr->rc = pro ;
}else if(pr->lc==NULL){
pr->lc = pro;
}
// printf("\n函数结束:setN\n");
}
Node* trvC(BT *a,Node *n){ //遍历数组找到我们需要的结点位置
// printf("\n进入函数:trvC\n");
Node *p = a->root;
Node *pre=NULL;
Node *t=NULL;
while(p){
//若树上结点级别小于该节点运算
if(getPriority(p->val,n->val)=='<'){
//若为数字,则用该符号替换,并将该数字作为其左孩
if(getIndex(p->rc->val)==-1){
t = p->rc;
p->rc = n;
n->lc = t;
break;
}else{
//若为字符,让更新p为该位置
pre = p;
p = p->rc;
}
}else{
//否则 让该运算符代替其,并让其成为右孩
if(a->root==p){
a->root = n;
}
n->lc = p;
if(pre)
pre->rc=n;
break;
}
}
return n;
// printf("\n函数结束:trvC\n");
}
Node* newNode(char c){ //新建结点并初始化
// printf("\n进入函数:newNode\n");
Node* pr = (Node*)malloc(sizeof(Node));
pr->val = c;
pr->lc=NULL;
pr->rc=NULL;
// printf("\n函数结束:newNode\n");
return pr;
}
void push(BT *a,char* s,int ic){
// printf("\n进入函数:push\n");
Node* p=NULL;
Node* pr = newNode(s[ic]); //新建前中后三个结点
Node* prl = newNode(s[ic+1]);
if(a->root==NULL){
a->root=pr;
Node* prf= newNode(s[ic-1]);
pr->rc=prl;
pr->lc=prf;
}else{
p=trvC(a,pr);
p->rc=prl;
}
// printf("\n函数结束:push\n");
}
float op(Node* n){ //计算子树运算结果
if(getIndex(n->val)==-1)return n->val-'0';
float a=0,b=0;
a=op(n->lc);
b=op(n->rc);
printf("\n计算:%.2f %c %.2f = ",a,n->val,b);
switch(n->val){
case '+':
printf("%.2f\n",a+b);
return a+b;
case '-':
printf("%.2f\n",a-b);
return a-b;
case '*':
printf("%.2f\n",a*b);
return a*b;
case '/':
printf("%.2f\n",a/b);
return (float)a/b;
}
}
float Cal(BT *a){
// printf("\n进入函数:Cal\n");
float rs=op(a->root);
// printf("\n函数结束:Cal\n");
return rs;
}; /*计算二叉树*/
int getIndex(char theta) //获取 theta 所对应的索引
{ int index = -1;
switch (theta){
case '+':
index = 0;break;
case '-':
index = 1;break;
case '*':
index = 2;break;
case '/':
index = 3;break;
case '(':
index = 4;break;
case ')':
index = 5;break;
default:break;
}
return index;
}
char getPriority(char theta1, char theta2) //获取 theta1 与 theta2 之间的优先级
{
const char priority[][7] =//算符间的优先级关系
{{ '<','<','<','<','<','>','>' },
{ '<','<','<','<','<','>','>' },
{ '>','>','<','<','<','>','>' },
{ '>','>','<','<','<','>','>' },
};
int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
int main(){
printf("================================================|| BT Calculator ||==================================================");
BT *a = (BT*) malloc(sizeof(BT));
char s[MaxS];
while(1){
printf("\n ============== FZC =============== \n\n");
Init(a,s);
Read(s);
if(s[0]=='#'){
printf("系统关闭!");
break;
}
BuildBT(a,s);
printf("\nFinal result:%.2f\n",Cal(a));
CLR(a->root);
}
return 0;
}
该系统缺陷在于设计时规定了每个数元取值在(0~9),若要更改,可以在push函数中修改;以及若括号出现在运算式的最前端可能会造成运算错误(若要改进,请在BuildBT中增加逻辑);以及括号内结果仍需维持在0~9以内,如(3+5)或(2*3),若要改进,需对结构体进行更改。
该代码仅供参考。