StackEmpty(S);i++)//
{
p=(BiTree)malloc(sizeof(BiTNode));
judge_value(&p,exprstring,i);/*将exprstring[i]存入二叉树的结点中*/
p->lchild=NULL;
p->rchild=NULL;
if(exprstring[i]=='+'||exprstring[i]=='-'||exprstring[i]=='*'||exprstring[i]=='/'||exprstring[i]=='^')
{/*为运算符,运算符入栈,左孩子不空,向左孩子走,否则,如果右孩子不空,向右孩子走*/
if(!
q->lchild){q->lchild=p;Push(&S,p);q=p;}
else{q->rchild=p;Push(&S,p);q=p;}
}
else/*不是运算符,运算符出栈*/
{
if(!
q->lchild){q->lchild=p;Pop(&S,&q);}
else{q->rchild=p;Pop(&S,&q);}
}
}
if(StackEmpty(S)&&i>=len)returnOK;/*栈空且i>=len,说明输入的表达式是正确的*/
else/*输入的表达式是错误的*/
{
printf("\n输入的表达式有误!
");
returnERROR;
}
}
}
/*如果两个字符是运算符,比较两个运算符的优先级,c1比c2优先,返回OK,否则返回ERROR*/
StatusPri_Compare(charc1,charc2)
{
if((c1=='^'||c1=='*'||c1=='-'||c1=='+'||c1=='/')&&(c2=='^'||c2=='*'||c2=='-'||c2=='+'||c2=='/'))
{/*c1和c2为运算符*/
if(c1=='^')/*c1为指数运算符,则当c2不为'^'时,c1比c2优先*/
{
if(c2!
='^')returnOK;
elsereturnERROR;
}
elseif(c1=='*'||c1=='/')/*c1为乘法或除法运算符,则当c2为'+'或'-',c1比c2优先*/
{
if(c2=='^'||c2=='*'||c2=='/')returnERROR;
elsereturnOK;
}
elsereturnERROR;/*其余,c1不比c2优先*/
}
elsereturnERROR;/*c1和c2不是运算符*/
}
/*用带括弧的中缀表达式输出表达式*/
voidWriteExpr(BiTreeE)
{
if(E)/*树不为空*/
{/*先递归左子树*/
if(E->lchild&&E->lchild->data.tag==CHAR)/*E的左孩子不为空,且左孩子为字符*/
{
if(Pri_Compare(E->data.c,E->lchild->data.c))/*E->data.c比E->lchild->data.c优先*/
{printf("(");
WriteExpr(E->lchild);
printf(")");}/*带括弧输出左子树*/
elseWriteExpr(E->lchild);/*否则,不带括弧输出左子树*/
}
elseWriteExpr(E->lchild);/*否则,输出左子树*/
/*访问输出根结点的值*/
if(E->data.tag==INT){printf("%d",E->data.num);}
elseprintf("%c",E->data.c);
/*后递归右子树*/
if(E->rchild&&E->rchild->data.tag==CHAR)/*E的右孩子不为空,且右孩子为字符*/
{
if(Pri_Compare(E->data.c,E->rchild->data.c))/*E->data.c比E->rchild->data.c优先*/
{printf("(");WriteExpr(E->rchild);printf(")");}/*带括弧输出右子树*/
elseWriteExpr(E->rchild);/*否则,不带括弧输出右子树*/
}
elseWriteExpr(E->rchild);/*否则,输出右子树*/
}
}
/*实现对表达式中的所有变量V的赋值(V=c),参数flag为表示是否赋值过的标志*/
voidAssign(BiTree*E,charV,intc,int*flag)
{
if(*E)
{
if((*E)->data.tag==CHAR&&(*E)->data.c==V)/*如果找到要赋值的变量,赋值*/
{(*E)->data.tag=INT;(*E)->data.num=c;*flag=1;}
Assign(&((*E)->lchild),V,c,flag);/*递归左子树*/
Assign(&((*E)->rchild),V,c,flag);/*递归左子树*/
}
}
/*指数运算函数,底数为x,指数为exp*/
longpower(intx,intexp)
{
longresult;
inti;
for(i=1,result=1;i<=exp;i++)
result*=x;
returnresult;
}
/*运算符运算求值,参数opr1,opr2为常量,opr为运算符,根据不同的运算符,实现不同的运算,返回运算结果*/
longOperate(intopr1,charopr,intopr2)
{
longresult;
switch(opr)
{
case'+':
/*加法*/
result=opr1+opr2;
returnresult;break;
case'-':
/*减法*/
result=opr1-opr2;
returnresult;break;
case'*':
/*乘法*/
result=opr1*opr2;
returnresult;break;
case'/':
/*除法,除法是在整型类型上的除法*/
result=opr1/opr2;
returnresult;break;
case'^':
/*指数运算*/
result=power(opr1,opr2);
returnresult;break;
default:
break;
}
}
/*运算符运算求值,参数opr为常量,opr1为运算符,根据不同的运算符,实现不同的运算,返回运算结果*/
doubleOperate1(charopr,doubleopr1)
{
doubleresult1,opr2;
opr2=opr1*2*pi/360;
switch(opr)
{
case's':
/*正玄sin*/
result1=sin(opr2);
returnresult1;break;
case'c':
/*余弦*/
result1=cos(opr2);
returnresult1;break;
case't':
/*正切*/
result1=tan(opr2);
returnresult1;break;
default:
break;
}
}
/*检查表达式是否还存在没有赋值的变量,以便求算数表达式的值*/
StatusCheck(BiTreeE)
{
if(E&&E->data.tag==CHAR)/*树不为空*/
{
if(E->data.c!
='*'&&E->data.c!
='^'&&E->data.c!
='-'&&E->data.c!
='+'&&E->data.c!
='/')
{printf("\n表达式中仍存在变量没有赋值!
没法求出表达式的值!
");returnERROR;}
/*存在变量,提示信息,后返回ERROR*/
if(Check(E->lchild))/*递归左子树*/
Check(E->rchild);/*递归右子树*/
}
}
/*对算术表达式求值*/
longValue(BiTreeE)
{
if(E)/*树不为空*/
{
if(!
E->lchild&&!
E->rchild&&E->data.tag==INT)return(E->data.num);
/*结点的左孩子和右孩子为空,为叶子结点,返回结点的值*/
returnOperate(Value(E->lchild),E->data.c,Value(E->rchild));
/*运算求值,后根遍历的次序对表达式求值,其中参数递归调用了Value()函数求左子树的值和右子树的值*/
}
}
/*构造一个新的复合表达式*/
voidCompoundExpr(charP,BiTree*E1,BiTreeE2)
{
BiTreeE;
E=(BiTree)malloc(sizeof(BiTNode));/*申请一个结点存放运算符P*/
E->data.tag=CHAR;
E->data.c=P;/*申请到的结点值为P*/
E->lchild=(*E1);/*结点的左孩子为E1*/
E->rchild=E2;/*结点的右孩子为E2*/
(*E1)=E;/*(*E1)为根结点*/
printf("\n表达式E复合成功!
其表达式变为:
\n");
WriteExpr(E);/*输出复合好的表达式*/
}
/*以表达式的原书写形式输入,表达式的原书写形式字符串string变为字符串pre_expr*/
/*后调用reversal_string()函数反转得到前缀表达式pre_expr*/
StatusRead_Inorder_Expr(char*string,char*pre_expr)
{
inti,j,len,char_number=1;/*len表示字符串string的长度,char_number是记录数组save_number[]的个数*/
intnumber;/*保存大于9的常量*/
charc,c1;
SqStack1S;/*栈定义*/
InitStack1(&S);/*初始栈*/
Push1(&S,'#');/*先将字符'#'入栈,用来表示作为栈的最底一个元素*/
len=strlen(string);/*len为字符串string的长度*/
c=string[len-1];/*从字符串的最后一个字符开始向前扫描*/
i=len-1;
while(!
StackEmpty1(S)&&i>=0)/*栈不为空且i大于等于0*/
{
if(c=='(')/*字符为'('*/
{
Pop1(&S,&c);/*出栈,赋值给c*/
while(c!
=')')/*假如c不为')',出栈*/
{
*pre_expr++=c;
if(!
StackEmpty1(S)&&GetTop1(S,&c1)&&c1!
='#')Pop1(&S,&c);
else{printf("\n输入的表达式有误!
");returnERROR;}
}
}
elseif(c==')')/*字符为')',入栈*/
{
Push1(&S,c);
}
elseif(c>='0'&&c<='9')/*字符为'0'-'9'之间,循环扫描string前一个字符,后确定常量的大小*/
{
number=c-48;/*number为第一个常量字符的ASCII码-48*/
for(c1=string[i-1],j=1;(c1>='0'&&c1<='9')&&i>=0;j++,i--)/*循环扫描string前一个字符,求出常量后
赋给number*/
{
number=(c1-48)*power(10,j)+number;/*number为扫描到的常量*/
c1=string[i-2];
}
save_number[char_number]=number;/*将number存入到数组save_number中,下标为
char_number*/
*pre_expr++=char_number++;
}
elseif((c>='a'&&c<='z')||(c>='A'&&c<='Z'))/*字符为'a'-'z'或'A'-'Z'之间的变量*/
{/*string下一个字符不能为常量或变量,否则,出错*/
if((string[i-1]>='0'&&string[i-1]<='9')||(string[i-1]>='A'&&string[i-1]<='Z')||(string[i-1]>='a'&&string[i-1]<='z'))
{printf("\n输入的表达式有误!
");returnERROR;}
else*pre_expr++=c;
}
elseif(c=='*'||c=='/')/*字符为运算符'*'或'/'*/
{
while(GetTop1(S,&c1)&&(c1=='^'))/*将c与栈顶的字符c1比较优先级*/
{Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c优先,出栈*/
Push1(&S,c);/*入栈字符c*/
}
elseif(c=='+'||c=='-')/*字符为运算符'+'或'-'*/
{
while(GetTop1(S,&c1)&&(c1=='^'||c1=='*'||c1=='/'))/*将c与栈顶的字符c1比较优先级*/
{Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c优先,出栈*/
Push1(&S,c);/*入栈运算符c*/
}
elseif(c=='^')/*字符为运算符'^'*/
{
Push1(&S,c);/*入栈运算符'^'*/
}
else{printf("\n输入的表达式有误!
");returnERROR;}/*其他字符,错误,返回ERROR*/
i--;/*下一个字符*/
if(i>=0)c=string[i];/*i不小于0,c=string[i]循环下一个字符*/
else/*否则,将清空栈*/
while(!
StackEmpty1(S)&&GetTop1(S,&c1)&&c1!
='#'){Pop1(&S,&c);*pre_expr++=c;}
}
Pop1(&S,&c);/*将'#'出栈*/
*pre_expr='\0';/*字符串结束符*/
if(i<0&&StackEmpty1(S))returnOK;
elsereturnERROR;
}
/*将字符串exprstring反转过来*/
voidreversal_string(char*exprstring)
{
intlen,i,j;
chartemp;
len=strlen(exprstring);/*len为exprstring的长度*/
for(i=0,j=len-1;i{
temp=exprstring[i];
exprstring[i]=exprstring[j];
exprstring[j]=temp;
}
}
/*常数合并操作函数,合并表达式E中所有常数运算*/
voidMergeConst(BiTree*E)
{
longresult;
if((*E)->lchild&&(*E)->rchild)/*左右孩子不为空*/
{
if((*E)->lchild->data.tag==INT&&(*E)->rchild->data.tag==INT)/*假如左右孩子为常量,合并*/
{
result=Operate((*E)->lchild->data.num,(*E)->data.c,(*E)->rchild->data.num);/*常数合并运算,调用
Operate()函数求值*/
(*E)->data.tag=INT;(*E)->data.num=result;/*修改之前的运算符为常量*/
free((*E)->lchild);/*释放左孩子*/
free((*E)->rchild);/*释放右孩子*/
(*E)->lchild=(*E)->rchild=NULL;/*左右孩子置空*/
}
else
{
MergeConst(&((*E)->lchild));/*递归左孩子*/
MergeConst(&((*E)->rchild));/*递归右孩子*/
}
}
}
//判断是否操作符
intisoperator(charc)
{
switch(c)
{
case'+':
returnTR