数据结构实验任务五:使用二叉树实现简单的加减乘除四则运算

使用二叉树实现一位的加减乘除运算(系统输入#结束):

数据结构实验任务五:使用二叉树实现简单的加减乘除四则运算_第1张图片

#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),若要改进,需对结构体进行更改。

该代码仅供参考。

你可能感兴趣的:(数据结构实验,数据结构,c语言,算法)