#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAXNUM 100
typedef int DataType;
struct BinTreeNode;
typedef struct BinTreeNode *PBinTreeNode;
struct BinTreeNode
{
DataType info;
PBinTreeNode llink;
PBinTreeNode rlink;
};
typedef struct BinTreeNode *BinTree;
typedef BinTree *PBinTree;
int infixtoBinTree(PBinTree pbtree, const char *infix,int n)
//从中缀表达式infix(长度为n)创建二叉树。若是一个合法的表达式,则返回TRUE
//且算法结束时*pbtree存放二叉树的根节点的地址;否则返回FALSE
{
char c;
int index,i,bracket;
int have_bracket=FALSE;
int num,state_int,nint;
int tag1,tag2;
if(infix[0]==' '||infix[0]=='\t'||infix[0]=='\n')
return infixtoBinTree(pbtree,infix+1,n-1);//忽略掉左边的若干空字符
if(infix[n-1]==' '||infix[0]=='\t'||infix[0]=='\n')
return infixtoBinTree(pbtree,infix,n-1);//忽略掉右边的若干空字符
if(infix[0]=='('&& infix[n-1]==')')
return infixtoBinTree(pbtree,infix+1,n-2);//忽略掉左右的成对括号
bracket=0; //bracket 为0,说明当前位置在层括号外部
index=n;
for(i=n-1;i>=0;i--)
{ //从后向前搜索,寻找到第一个不再括号中的优先级最低的运算符
c=infix[i];
if(c==')')
{
have_bracket=TRUE;
bracket++; // 进入一层括号
}
if(c=='(') bracket--; // 出一层括号
if(bracket<0)
{
*pbtree=NULL;
return FALSE; // 左右两边括号不向匹配,表达式非法
}
if(bracket>0)continue;// 若当前位置在某层括号中,直接搜索下个位置
if(c=='+'||c=='-')
if(index==n||infix[index]=='*'||infix[index]=='/')index=i;
if(c=='*'||c=='/')
if(index==n)index=i;
}
if(bracket!=0) return FALSE; //左右两边括号不相匹配,表达式非法
if(index==n) // 说明这是一个只含一个数字和若干空字符的表达式,相应的创建一颗只含一个根节点的二叉树
{
if(have_bracket==TRUE)
{
*pbtree=NULL;
return FALSE;
}//不应含括号
nint=0; //nint 记录表达式中含有的整数个数
state_int=FALSE;//state_int 记录当前读入的字符是否是数字字符
num=0;
for(i=0;i<n;i++)
{
c=infix[i];
switch(c)
{
case'0':case'1':case'2':case'3':case'4':
case'5':case'6':case'7':case'8':case'9':
if(state_int==FALSE)
{
num=c-'0';
state_int=TRUE;
nint++;
}
else
{
num=num*10+c-'0';
}
break;
case' ':case'\t':case'\n':
state_int=FALSE;
break;
default:
*pbtree=NULL;
return FALSE;
}
}
if(nint!=1)
{
*pbtree=NULL;
return FALSE;
} //此时表达式中应恰含一个整数
*pbtree=(BinTree)malloc(sizeof(struct BinTreeNode));
(*pbtree)->info=num;
(*pbtree)->llink=NULL;
(*pbtree)->rlink=NULL;
return TRUE; //成功创建一个只含一个根结点的二叉树
}
*pbtree=(BinTree)malloc(sizeof(struct BinTreeNode));
(*pbtree)->info=infix[index];
tag1=infixtoBinTree(&(*pbtree)->llink,infix,index);// 递归调用本算法创建左子树
tag2=infixtoBinTree(&(*pbtree)->rlink,infix+index+1,n-index-1);// 递归调用本算法创建右子树
if(tag1==TRUE&&tag2==TRUE)return TRUE;
return FALSE;
}
int calculate(BinTree btree,int *presult)
{//计算二叉树btree所代表的表达式的值,若是一个合法的表达式,则返回TRUE,
//且算法结束时*presult中存放计算结果;否则,返回FALSE
int result1,result2;
if(btree==NULL)return FALSE; //空树 无法计算
if(btree->llink==NULL||btree->rlink==NULL)
{
*presult=btree->info;
return TRUE;//只有一个结点
}
if(btree->llink==NULL||btree->rlink==NULL)
{
return FALSE;//只有左子树或只有右子数,无法计算
}
switch(btree->info)
{
case'+':
if(calculate(btree->llink,&result1)==FALSE)return FALSE;
if(calculate(btree->rlink,&result2)==FALSE)return FALSE;
*presult=result1+result2;
return TRUE;
case'-':
if(calculate(btree->llink,&result1)==FALSE)return FALSE;
if(calculate(btree->rlink,&result2)==FALSE)return FALSE;
*presult=result1-result2;
return TRUE;
case'*':
if(calculate(btree->llink,&result1)==FALSE)return FALSE;
if(calculate(btree->rlink,&result2)==FALSE)return FALSE;
*presult=result1*result2;
return TRUE;
case'/':
if(calculate(btree->llink,&result1)==FALSE)return FALSE;
if(calculate(btree->rlink,&result2)==FALSE)return FALSE;
*presult=result1/result2;
return TRUE;
default:
return FALSE;
}
}
void delete_BTree(PBinTree ptree)
{
BinTree temp=(*ptree);
if(temp==NULL)return;
delete_BTree(&(temp->llink));
delete_BTree(&(temp->rlink));
free(temp);
}
void getline(char *line,int limit)//从标准输入中读入一行,作为字符串line
{
char c;
int i=0;
while(i<limit-1 && (c=getchar())!=EOF&&c!='\n')
line[i++]=c;
line[i]='\n';
}
int main()
{
char c,infix[MAXNUM];
// char infix[MAXNUM]={'2','0','+','(','3','*','(','4','+','4','6',')','-','6',')','/','2','-','1','3','4'};
int result,flag=TRUE;
BinTree btree;
while(flag==TRUE)
{
printf("请输入一个中缀表达式:\nInput:");
getline(infix,MAXNUM);//读入中缀表达式
if(infixtoBinTree(&btree,infix,strlen(infix))==FALSE)
{
printf("无效的中缀表达式!\n");
delete_BTree(&btree);
printf("\nContinue?(y/n)");
scanf("%c",&c);
if(c=='n'||c=='N')flag=FALSE;
while(getchar()!='\n');
printf("\n");
continue;
}
if (calculate(btree,&result)==TRUE)printf("Result:%d\n",result);
else printf("无效的输入!\n");
delete_BTree(&btree);
printf("\nContinue?(y/n)");
scanf("%c",&c);
if(c=='n'||c=='N')flag=FALSE;
while(getchar()!='\n');
printf("\n");
}
return 0;
}
数据结构源码笔记(C语言描述)汇总: