无聊小练一下数据结构,表达式求值
#include
#include
#include
typedef struct BITNODE
{
int flag; //0没用过,1数字节点,2符号节点
char sign;
float number;
struct BITNODE *lchild,*rchild;
}BitNode,*BiTree;
typedef struct LINKLIST
{
struct BITNODE *treeNode;
struct LINKLIST *nextNode;
struct LINKLIST *lastNode;
}linkNode,*LinkList;
/////////////////+, -, *, /, (, ),\0,//////////
int priority[7][7]={ 1, 1,-1,-1,-1, 1, 1, //优先算符表
1, 1,-1,-1,-1, 1, 1,
1, 1, 1, 1,-1, 1, 1,
1, 1, 1, 1,-1, 1, 1,
-1,-1,-1,-1,-1, 0, 0,
1, 1, 1, 1, 0, 1, 1,
-1,-1,-1,-1,-1, 0, 0};
int stackTopBiTree=-1; //栈顶指针
int stackTopSign=-1;
BiTree stackB[100];
char stackC[100];
///////////////////////////////////////////////
BiTree popB() //进出栈函数
{
return stackB[stackTopBiTree--];
}
void pushB(BiTree biTree)
{
stackB[++stackTopBiTree]=biTree;
}
///////////////////////////////////////////
char popC()
{
return stackC[stackTopSign--];
}
void pushC(char sign)
{
stackC[++stackTopSign]=sign;
}
BiTree outList(LinkList &list)
{
if(!list->nextNode) return NULL;
if(!list->nextNode->nextNode) list->lastNode=list; //如果全出完了把最后
LinkList tempList; //结点放在头结点
BiTree tempTree;
tempList=list->nextNode;
tempTree=list->nextNode->treeNode;
list->nextNode=list->nextNode->nextNode;
free(tempList); //释放链表接点
return tempTree;
}
void inList(LinkList &list,BiTree treeNode)
{
LinkList listNode;
listNode=(LinkList)malloc(sizeof(linkNode));
listNode->treeNode=treeNode; //从最后一个进栈
listNode->nextNode=NULL;
listNode->lastNode=NULL;
list->lastNode->nextNode=listNode; //链表最后一个指向下一个
list->lastNode=listNode; //更新最后一个的位置
}
void ccPrintTree(BiTree node)
{
if(!node){
printf("空树!");
return;
}
LinkList list;
list=(LinkList)malloc(sizeof(LinkList));
list->nextNode=NULL;
list->treeNode=NULL;
list->lastNode=list;
inList(list,node);
BiTree temp;
while(list->nextNode) {
temp = outList(list);
if(temp->lchild) inList(list,temp->lchild); //还有结点入栈
if(temp->rchild) inList(list,temp->rchild);
if(temp->flag==1) printf("\t%f",temp->number);
else printf("\t%c",temp->sign);
}
}
void InitHead(BiTree &L) //初始化树
{
L=(BiTree)malloc(sizeof(BitNode));
L->lchild=NULL;
L->rchild=NULL;
L->sign='\0';
L->number=0;
L->flag=0;
}
float reap(char *exp,int position1,int position2) //获得两个算符之间的数字
{
int pot=position1+1,i=0; //pot是小数点的位置
float numHigh=0.0,numLow=0.0; //存放数字的小数点之前和之后的数
char *p=exp+position1+1;
while((*(p+i)!='.')&&(pot!=position2)) {
i++;
pot++;
}
for(int j=0;jlchild=nodeA;
signNode->rchild=nodeB;
signNode->sign=sign;
signNode->flag=2;
return signNode;
}
char Precede(char top,char follow) //确定优先性函数
{
int i=0,j=0;
switch(top){
case '+': i=0; break;
case '-': i=1; break;
case '*': i=2; break;
case '/': i=3; break;
case '(': i=4; break;
case ')': i=5; break;
case '\0': i=6; break;
default: printf("error\n");
}
switch(follow){
case '+': j=0; break;
case '-': j=1; break;
case '*': j=2; break;
case '/': j=3; break;
case '(': j=4; break;
case ')': j=5; break;
case '\0': j=6; break;
default: printf("error\n");
}
switch(priority[i][j]){
case 0: return '=';
case 1: return '>';
case -1: return '<';
}
return 'e';
}
void InitExpTree(BiTree &L)
{
InitHead(L);
printf("please input the express:");
char *exp=(char*)malloc(sizeof(char)*255);
scanf("%s",exp); //获得表达式
int haveNum=0,i=0;
char sign;
int position1=-1,position2=1; //记录符号位置
stackTopBiTree=-1; //初始化栈顶
stackTopSign=-1;
pushC('\0'); //把空字符压入堆栈
while(*(exp+i)!='\0'||stackC[stackTopSign]!='\0') { //当都为结束符号时
if((*(exp+i)<'0'||*(exp+i)>'9')&&(*(exp+i)!='.')){
position2=i; //新的符号的位置
if(haveNum==1) { //出现了数字开关,需要提取数字
BiTree nodeNum =(BiTree)malloc(sizeof(BiTree));
nodeNum->flag=1;
nodeNum->lchild=NULL;
nodeNum->rchild=NULL;
nodeNum->number=reap(exp,position1,position2);
pushB(nodeNum);
haveNum=0;
}
switch(Precede(stackC[stackTopSign],*(exp+i))) { //比较
case '<':
pushC(*(exp+i)); //栈顶优先小,压堆栈
position1=position2; //更新符号位置
i++; //表达式后移
break;
case '=':
popC(); //脱括号
position1=position2;
i++;
break;
case '>':
sign=popC(); //符号和数出栈进行计算
BiTree t1,t2;
t2=popB();
t1=popB();
pushB(CreatTreeNode(t1,sign,t2));
break;
default:
printf("errorout!"); //出错保护
break;
}
}else {
haveNum=1;
i++;
}
}
L=popB();
}
BiTree CalculateTree(BiTree tree)
{
float leftValue,rightValue;
BiTree temp1,temp2;
if(tree->lchild->flag==2) { //左边结点是符号,继续算
temp1=CalculateTree(tree->lchild);
leftValue=temp1->number;
// free(temp1);
}else{ //左边结点已经是数字了
leftValue=tree->lchild->number;
}
if(tree->rchild->flag==2){
temp2=CalculateTree(tree->rchild);
rightValue=temp2->number;
//free(temp2);
}else{
rightValue=tree->rchild->number;
}
BiTree newNode=(BiTree)malloc(sizeof(BiTree));
newNode->flag=1; //把算好后的结果组成新的数字结点返回
newNode->lchild=NULL;
newNode->rchild=NULL;
switch(tree->sign)
{
case '+': newNode->number=leftValue+rightValue;
break;
case '-': newNode->number=leftValue-rightValue;
break;
case '*': newNode->number=leftValue*rightValue;
break;
case '/': newNode->number=leftValue/rightValue;
break;
}
return newNode;
}
void PrePrintTree(BiTree node) //先序输出
{
if(node->flag==2) printf("%c ",node->sign);
else printf("%f ",node->number);
if((node->lchild)) PrePrintTree(node->lchild);
if((node->rchild)) PrePrintTree(node->rchild);
}
void MidPrintTree(BiTree node) //中序输出
{
if((node->lchild)) MidPrintTree(node->lchild);
if(node->flag==2) printf("%c ",node->sign);
else printf("%f ",node->number);
if((node->rchild)) MidPrintTree(node->rchild);
}
void FolPrintTree(BiTree node) //后序输出
{
if((node->lchild)) FolPrintTree(node->lchild);
if((node->rchild)) FolPrintTree(node->rchild);
if(node->flag==2) printf("%c ",node->sign);
else printf("%f ",node->number);
}
void DeleteTree(BiTree node)
{
if(!node)
return ;
if((node->lchild==NULL)&&(node->lchild==NULL)){
free(node);
return;
}
if(node->lchild) DeleteTree(node->lchild);
if(node->rchild) DeleteTree(node->rchild);
}
void TablePrintTree(BiTree node,int tt) //广义表输出
{
int t=0,tSign=0; //t是右括号开关,tt和tSign都是,开关
if(node->flag==2) {
printf("%c(",node->sign); //输出符号
if(tt) tSign=1; //如果符号结点也是左结点,后面括号后面也要加一个标点
} else {
printf("%f ",node->number);
if(tt) printf(", "); //如果是左结点输出点号
t=1;
}
if((node->lchild)) TablePrintTree(node->lchild,1);
if((node->rchild)) TablePrintTree(node->rchild,0);
if(t==0) printf(")"); //如果是符号的循环就输出右括号
if(tSign) printf(", ");
}
void main()
{
BiTree L;
InitExpTree(L);
printf("前缀式输出:");
PrePrintTree(L);
printf("\n中缀式输出:");
MidPrintTree(L);
printf("\n后缀式输出:");
FolPrintTree(L);
printf("\n层次输出:");
ccPrintTree(L);
printf("\n值为:%f",CalculateTree(L)->number);
printf("\n广义表为:");
TablePrintTree(L,0);
}