数据结构二叉树类型的实现.docx

上传人:b****6 文档编号:4439693 上传时间:2022-12-01 格式:DOCX 页数:23 大小:23.88KB
下载 相关 举报
数据结构二叉树类型的实现.docx_第1页
第1页 / 共23页
数据结构二叉树类型的实现.docx_第2页
第2页 / 共23页
数据结构二叉树类型的实现.docx_第3页
第3页 / 共23页
数据结构二叉树类型的实现.docx_第4页
第4页 / 共23页
数据结构二叉树类型的实现.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

数据结构二叉树类型的实现.docx

《数据结构二叉树类型的实现.docx》由会员分享,可在线阅读,更多相关《数据结构二叉树类型的实现.docx(23页珍藏版)》请在冰豆网上搜索。

数据结构二叉树类型的实现.docx

数据结构二叉树类型的实现

实验4表达式二叉树类型的实现

源代码及每步注解:

文件expression.h

/*头文件以及存储结构*/

#include

#include

#include

#include

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineOVERFLOW0

typedefintStatus;

/*二叉树结点类型*/

typedefenum{INT,CHAR}ElemTag;/*INT为整型数据num,CHAR为字符型数据c*/

typedefstructTElemType

{

ElemTagtag;/*{INT,CHAR}指示是整型还是字符型*/

union

{

intnum;/*tag=INT时,为整型*/

charc;/*tag=CHAR时,为字符型*/

};

}TElemType;

/*二叉树的二叉链表存储表示*/

typedefstructBiTNode

{

TElemTypedata;

structBiTNode*lchild,*rchild;/*左右孩子指针*/

}BiTNode,*BiTree;

typedefBiTreeSElemType;/*栈SqStack的元素*/

typedefcharSElemType1;/*栈SqStack1的元素*/

/*栈的顺序存储表示*/

#defineSTACK_INIT_SIZE10/*存储空间初始分配量*/

#defineSTACKINCREMENT2/*存储空间分配增量*/

/*两个顺序栈*/

typedefstructSqStack

{

SElemType*base;/*在栈构造之前和销毁之后,base的值为NULL*/

SElemType*top;/*栈顶指针*/

intstacksize;/*当前已分配的存储空间,以元素为单位*/

}SqStack;/*顺序栈*/

typedefstructSqStack1

{

SElemType1*base;/*在栈构造之前和销毁之后,base的值为NULL*/

SElemType1*top;/*栈顶指针*/

intstacksize;/*当前已分配的存储空间,以元素为单位*/

}SqStack1;/*顺序栈*/

/*顺序栈的基本操作*/

StatusInitStack(SqStack*S)

{/*构造一个空栈S*/

(*S).base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

if(!

(*S).base)

exit(OVERFLOW);/*存储分配失败*/

(*S).top=(*S).base;

(*S).stacksize=STACK_INIT_SIZE;

returnOK;

}

StatusStackEmpty(SqStackS)

{/*若栈S为空栈,则返回TRUE,否则返回FALSE*/

if(S.top==S.base)returnTRUE;

elsereturnFALSE;

}

StatusPush(SqStack*S,SElemTypee)

{/*插入元素e为新的栈顶元素*/

if((*S).top-(*S).base>=(*S).stacksize)/*栈满,追加存储空间*/

{

(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));

if(!

(*S).base)exit(OVERFLOW);/*存储分配失败*/

(*S).top=(*S).base+(*S).stacksize;

(*S).stacksize+=STACKINCREMENT;

}

*((*S).top)++=e;

returnOK;

}

StatusPop(SqStack*S,SElemType*e)

{/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/

if((*S).top==(*S).base)returnERROR;

*e=*--(*S).top;

returnOK;

}

StatusGetTop(SqStackS,SElemType*e)

{/*若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR*/

if(S.top>S.base)

{

*e=*(S.top-1);

returnOK;

}

else

returnERROR;

}

/*顺序栈的基本操作*/

StatusInitStack1(SqStack1*S)

{/*构造一个空栈S*/

(*S).base=(SElemType1*)malloc(STACK_INIT_SIZE*sizeof(SElemType1));

if(!

(*S).base)

exit(OVERFLOW);/*存储分配失败*/

(*S).top=(*S).base;

(*S).stacksize=STACK_INIT_SIZE;

returnOK;

}

StatusStackEmpty1(SqStack1S)

{/*若栈S为空栈,则返回TRUE,否则返回FALSE*/

if(S.top==S.base)returnTRUE;

elsereturnFALSE;

}

StatusPush1(SqStack1*S,SElemType1e)

{/*插入元素e为新的栈顶元素*/

if((*S).top-(*S).base>=(*S).stacksize)/*栈满,追加存储空间*/

{

(*S).base=(SElemType1*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType1));

if(!

(*S).base)exit(OVERFLOW);/*存储分配失败*/

(*S).top=(*S).base+(*S).stacksize;

(*S).stacksize+=STACKINCREMENT;

}

*((*S).top)++=e;

returnOK;

}

StatusPop1(SqStack1*S,SElemType1*e)

{/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/

if((*S).top==(*S).base)returnERROR;

*e=*--(*S).top;

returnOK;

}

StatusGetTop1(SqStack1S,SElemType1*e)

{/*若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR*/

if(S.top>S.base)

{

*e=*(S.top-1);

returnOK;

}

else

returnERROR;

}

 

文件expression.cpp

 

#include"expression.h"

/*全局变量*/

intsave_number[31];/*在按原表达式输入形式中,输入的常量保存到数组save_number中,常量最多为30个,0单元不用*/

charExpr_String[30];/*存放表达式的字符串*/

/*以字符序列的形式输入语法正确的前缀表达式,保存到字符串string*/

/*参数flag=0表示输出的提示信息是"请输入正确的前缀表示式:

"*/

/*flag=1表示输出的提示信息为"请以表达式的原书写形式输入正确表示式:

"*/

StatusInput_Expr(char*string,intflag)

{

if(flag==0)printf("\n请输入正确的前缀表示式:

");

elseprintf("\n请以表达式的原书写形式输入正确表示式:

");

flushall();/*清理缓冲区*/

gets(string);/*从键盘输入一串字符串作为表达式*/

if(strlen(string)==1)/*输入的表达式字符串长度为1*/

if(string[0]=='+'||string[0]=='-'||string[0]=='*'||string[0]=='/'||string[0]=='^')/*输入的表达式只有一个运算符*/

{printf("\n表达式只有一个字符,为运算符,错误!

");returnERROR;}

elseif((string[0]>='0'&&string[0]<'9')||(string[0]>='a'&&string[0]<='z')||(string[0]>='A'&&string[0]<='Z'))

/*输入的表达式只有一个数字或字符*/

{printf("\n表达式只有一个字符!

");returnOK;}

else{printf("\n输入的字符不是运算符也不是变量常量,错误!

");returnERROR;}

returnOK;

}

/*判断字符string[i],如果是'0'-'9'常量之间,二叉树结点存为整型;否则,存为字符型*/

voidjudge_value(BiTree*E,char*string,inti)

{

if(string[i]>='0'&&string[i]<='9')/*为常量*/

{(*E)->data.tag=INT;(*E)->data.num=string[i]-48;}

elseif(string[i]>=1&&string[i]<=20)/*为常量,常量存于数组save_number中*/

{(*E)->data.tag=INT;(*E)->data.num=save_number[string[i]];}

else/*为变量*/

{(*E)->data.tag=CHAR;(*E)->data.c=string[i];}

}

/*以正确的前缀表示式并构造表达式E*/

StatusReadExpr(BiTree*E,char*exprstring)

{

SqStackS;

inti,len;/*len为表达式的长度*/

BiTreep,q;

(*E)=(BiTree)malloc(sizeof(BiTNode));/*申请二叉树的根结点的空间*/

(*E)->lchild=NULL;

(*E)->rchild=NULL;

len=strlen(exprstring);/*len赋值为表达式的长度*/

if(len==1)/*表达式长度为1时,二叉树只有根结点*/

judge_value(E,exprstring,0);/*将exprstring[0]存入二叉树的结点中*/

else

{

judge_value(E,exprstring,0);/*将exprstring[0]存入二叉树的结点中*/

InitStack(&S);/*初始化栈*/

q=(*E);

Push(&S,q);/*入栈*/

Push(&S,q);/*入栈,根结点入栈两次是为判断先序输入的表达式是不是正确的表达式*/

for(i=1;i

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;

}

}

/*检查表达式是否还存在没有赋值的变量,以便求算数表达式的值*/

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=='('

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 学科竞赛

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1