C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现.docx
- 文档编号:9198948
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:21
- 大小:19.02KB
C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现.docx
《C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现.docx》由会员分享,可在线阅读,更多相关《C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现.docx(21页珍藏版)》请在冰豆网上搜索。
C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现
/*
名称:
中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现
内容:
1、掌握栈的存储结构的C语言描述
2、掌握中缀表达式转换为后缀表达式的算法实现
3、掌握后缀表达式计算算法的实现
要求:
程序功能包括:
主程序;
表达式的输入、转换;
后缀表达式的输出、计算和数据的输出。
名称
二叉树的建立与遍历及二叉树中序线索化及线索化遍历的实现
内容
掌握二叉树的建立与遍历的算法实现
掌握二叉树中序线索化及线索化遍历的算法实现
要求
程序功能包括:
主程序;二叉树的建立、二叉树的遍历(前序、中序、后序)、二叉树中序
线索化、线索化遍历和输出等
实验报告:
程序流程图;上机通过的程序(清单);总结二叉树遍历的特点
*/
/*
函数:
1、线索二叉树(左孩子、右孩子、左线索标志、右线索标志、双亲、数据域)
2、建立二叉树
3、前、中、后序扫描二叉树
4、中序线索化二叉树
5、中序遍历线索二叉树
6、线索二叉树查找
7、线索二叉树插入
功能:
1、二叉树的输入实现(输入根、左、右的顺序,当左或右为空时输入0,以‘#’结束输入)(输入优化)
2、前、中、后序扫描二叉树输出扫描结果
3、二叉树中序线索化
4、二叉树线索化遍历
*/
/*
#include
#include
#include
#definemaxsize100
typedefchardatatype;
typedefstructnode
{
intltag,rtag;
datatypedata;
structnode*lchild,*rchild;//*parent;
}bitree;
bitree*root;
bitree*pre;
bitree*Q[maxsize];
bitree*creatree()
{
charch;
intfront,rear;//队头、队尾指针
bitree*root,*s;
root=NULL;//置空二叉树
front=1;rear=0;//置空队列
printf("\t\t>>>请输入二叉树(无孩子输入'@'并以'#'结束):
\n\t\t");
ch=getchar();//输入第一个字符
while(ch!
='#')//不是结束符时重复做
{
s=NULL;
if(ch!
='@')//@表示虚结点,不是虚结点时建立新结点
{
s=(bitree*)malloc(sizeof(bitree));
s->data=ch;
s->lchild=NULL;
s->rchild=NULL;
s->ltag=0;
s->rtag=0;
}
rear++;
Q[rear]=s;//将虚结点指针NULL或新结点地址入队
if(rear==1)root=s;//输入的第一个结点为根结点
else
{
if(s&&Q[front])//孩子和双亲结点均不是虚结点
if(rear%2==0)Q[front]->lchild=s;//rear为偶数,新结点为左孩子
else//rear为奇数
Q[front]->rchild=s;//新结点是右孩子
if(rear%2==1)front++;//结点*Q[front]的两个孩子已经处理完毕,出队列
}
ch=getchar();//输入下一个字符
}
returnroot;//返回根指针
}
//关于建立新树:
输入处理(关于完全二叉树)
//中序遍历
voidinorder(bitree*t)
{
if(t)//二叉树非空
{
inorder(t->lchild);//中序遍历t的左子树
printf("%c",t->data);//访问结点t
inorder(t->rchild);//中序遍历t的右子树
}
}
//前序遍历
voidpreorder(bitree*t)
{
if(t)//二叉树非空
{
printf("%c",t->data);//访问结点t
preorder(t->lchild);//中序遍历t的左子树
preorder(t->rchild);//中序遍历t的右子树
}
}
//后序遍历
voidpostorder(bitree*t)
{
if(t)//二叉树非空
{
postorder(t->lchild);//中序遍历t的左子树
postorder(t->rchild);//中序遍历t的右子树
printf("%c",t->data);//访问结点t
}
}
voidinthread(bitree*p)//将二叉树p中序线索化,线索标志初值为0
{
if(p!
=NULL)
{
inthread(p->lchild);//左子树线索化
if(p->lchild==NULL)p->ltag=1;//建立左线索标志
if(p->rchild==NULL)p->rtag=1;//建立右线索标志
if(pre!
=NULL)
{
if(pre->rtag==1)//p无右子树
pre->rchild=p;//右线索p->rchild为p
if(pre->ltag==1)//p无左子树
pre->lchild=pre;//左线索p->lchild为pre
}
pre=p;
inthread(p->rchild);//右子树线索化
}
}
//在中序线索树中找结点*p的中序后继
bitree*inordernext(bitree*p)
{
bitree*q;
if(p->rtag==1)//p右子树为空
return(p->rchild);//p->rchild是右线索,指向p的后继
else//p的右子树非空
{
q=p->rchild;//从p的右孩子开始查找
while(q->ltag==0)//当q不是左下结点时,继续查找
q=q->lchild;
return(q);
}
}
//遍历中序线索二叉树p
voidtravereinthread(bitree*p)
{
if(p!
=NULL)//非空树
{
while(p->ltag==0)//找中序序列的开始结点
p=p->lchild;
do
{
printf("%c",p->data);//访问结点p
p=inordernext(p);//找p的中序后继结点
}while(p!
=NULL);
}
}
voidmain()
{
bitree*p;inta=0;
printf("\t\t**********************************************\n");
printf("\t\t************二叉树************\n");
printf("\t\t**********************************************\n\n");
p=creatree();//创建二叉树
printf("\n");
printf("\t\t二叉树的前序遍历结果为:
\n");//前序遍历
printf("\t\t");preorder(p);printf("\n");
printf("\t\t二叉树的中序遍历结果为:
\n");//中序遍历
printf("\t\t");inorder(p);printf("\n");
printf("\t\t二叉树的后序遍历结果为:
\n");//后序遍历
printf("\t\t");postorder(p);printf("\n");
inthread(p);//中序线索化
printf("\t\t二叉树的中序线索化遍历结果为:
\n");//后序遍历
printf("\t\t");
travereinthread(p);//中序线索话遍历
printf("\t\t");
getch();
}
*/
/*
//在结点p、p的右子树之间插入新结点q
insertright(bithptr*p,bithptr*q)
{
bithptr*s;
s=inordernext(p);//查找p的原中序后继结点
q->ltag=1;//建立q的左线索标志
q->lchild=p;//q的中序前趋为p
q->rtag=p->rtag;
q->rchild=p->rchild;//q的右子树或右线索等于原p的右子树或右线索
p-ratag=0;
p->rchild=q;//新结点q作为p的右孩子
if((s!
=NULL)&&(s->ltag==1))
s->lchild=q;//结点s的左链是线索,s的前趋是p
}
*/
/*
#include
#include
#include
#include
typedefstructnode//定义栈结构体类型
{
booln;//标志操作数和操作符
charoperate;//操作符
floatnum;//操作数
structnode*next;
}stack;
structchangenum//临时变量
{
boolw;
floatnum;
charop;
stack*q;
};
stack*InitStack()//初始化堆栈
{
stack*S;
S=(stack*)malloc(sizeof(stack));
S->n=0;
S->num=0;
S->operate=0;
S->next=NULL;
returnS;
}
stack*push(stack*top,booln,floatnum,charoperate)//进栈函数
{
stack*p;
p=(stack*)malloc(sizeof(stack));//生成新节点
if(n==0)//进栈的为浮点数
{
p->n=0;
p->operate=NULL;
p->num=num;
}
if(n==1)//进栈的为操作符
{
p->n=1;
p->operate=operate;
p->num=NULL;
}
p->next=top;
top=p;
returnp;
}
changenum*pop(stack*top)//退栈函数
{
stack*p;
changenum*sp;
sp=(changenum*)malloc(sizeof(changenum));
if(top->next==NULL){printf("underflow!
\n");returnNULL;}//栈下溢
else//退栈操作
{
p=top;
top=top->next;
sp->q=top;
sp->num=p->num;
sp->op=p->operate;
sp->w=0;
returnsp;
}
}
//*******************************************
//****************栈定义及操作***************
//后缀表达式的存储
//*******************************************
typedefstructnode2
{
booln;//标志操作数和操作符
floatnum;//操作数
charoperate;//操作符
structnode2*front,*rear,*next;//队头队尾指针
}squeue;//定义队列类型
squeue*q;
squeue*InitQueue()//初始化队列
{
squeue*Q;
Q=(squeue*)malloc(sizeof(squeue));
Q->n=0;
Q->front=Q;
Q->num=12345;
Q->operate=0;
Q->front->next=NULL;
Q->rear=Q;
returnQ;
}
voidenqueue(squeue*q,booln,floatnumber,charop)//入队操作
{
if(op==')');
else
{
q->rear->next=(squeue*)malloc(sizeof(squeue));
q->rear=q->rear->next;
if(n==0)
{
q->rear->n=0;
q->rear->operate=NULL;
q->rear->num=number;
}
if(n==1)
{
q->rear->n=1;
q->rear->operate=op;
q->rear->num=NULL;
}
q->rear->next=NULL;
}
}
changenum*dequeue(squeue*q)//出队操作
{
squeue*s;
changenum*sp;
sp=(changenum*)malloc(sizeof(changenum));
if(q->front->next==NULL){sp->num=q->num;sp->w=q->n;}
else
{
s=q->front->next;
q->front->next=s->next;
sp->w=s->n;
sp->num=s->num;
sp->op=s->operate;
}
returnsp;
}
//*******************************************
//****************队定义及操作***************
//实现表达式的临时存储
//*******************************************
intpriority(charch)//操作符及操作数优先级判断
{
switch(ch)
{
case'+':
case'-':
return2;
case'*':
case'/':
return3;
case'(':
case'#':
return1;
case')':
return4;
case'':
return10;
case'.':
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
return0;
default:
printf("ERROR!
");return5;
}
}
changenum*getlist(charch)//将字符数组转为float类型变量
{
changenum*sp;
sp=(changenum*)malloc(sizeof(changenum));
if(priority(ch)==0)
{
sp->w=0;
intp=1;
floatsum=0,point=0;
chara[40];
intm=0;
intn=1;
for(inti=0;i<=39;i++)
a[i]=0;
while(ch!
='.'&&priority(ch)==0)
{
a[m]=ch;sum=sum*10+(a[m]-'0');m++;//整数部分
ch=getchar();
}
if(ch=='.')
{
ch=getchar();
while(priority(ch)==0)//小数部分处理
{
a[m+n]=ch;point=point*10+(a[m+n]-'0');p=p*10;n++;
ch=getchar();
}
}
sum=sum+point/p;//转为浮点数
sp->num=sum;
sp->op=ch;
returnsp;
}
else
{
sp->w=1;
sp->num=100;
sp->op=100;
returnsp;
}
}
floatchange()//输入中缀表达式并转换为后缀表达式、输出后缀表达式并计算结果
{
stack*formula1;squeue*formula2,*formula4;stack*formula3;
chara,ch;booli;changenum*mark,*sign;
formula2=InitQueue();
formula4=InitQueue();
formula1=InitStack();
formula3=InitStack();
formula3=push(formula3,1,0,'#');
formula1=push(formula1,1,0,'#');
printf("请输入表达式以#结束:
\n");
ch=getchar();
do
{
mark=getlist(ch);
i=mark->w;
if(i==0)
{
enqueue(formula2,0,mark->num,0);enqueue(formula4,0,mark->num,0);ch=mark->op;free(mark);//将操作数入队
}
else
{
switch(ch)//操作符处理
{
case'(':
formula1=push(formula1,1,0,ch);break;//将做括号压入栈S
case')':
if(formula1->operate=='#'){printf("括号不匹配!
!
!
\n");return1;}
else
{
do
{
sign=pop(formula1);formula1=sign->q;
a=sign->op;
if(a=='(')break;
elseif(priority(a)==4);
else{enqueue(formula2,1,0,a);enqueue(formula4,1,0,a);}
}
while(a!
='#');
if(a=='#'){printf("括号不匹配!
!
!
\n");return1;}
}
case'+':
case'-':
case'*':
case'/':
while(formula1->operate!
='#'&&formula1->operate!
='('&&priority(formula1->operate)>=priority(ch))
{
sign=pop(formula1);formula1=sign->q;enqueue(formula2,1,0,sign->op);enqueue(formula4,1,0,sign->op);
}
formula1=push(formula1,1,0,ch);
break;
case'#':
break;
default:
printf("ERROR!
!
!
\n");return1;
}
ch=getchar();
}
}
while(ch!
='#');//表达式扫描结束条件
//表达式扫描结束后若栈中还有元素则依次弹出输入的后缀表达式中
while(formula1->operate!
='#')
{
sign=pop(formula1);formula1=sign->q;
if(sign->op=='('){printf("括号不匹配!
!
!
\n");return1;}
else{enqueue(formula2,1,0,sign->op);enqueue(formula4,1,0,sign->op);}
}
printf("后缀表达式为:
\n");
do//后缀表达式的输出
{
mark=dequeue(formula2);
if(mark->num==12345)break;
if(mark->w==0)
{printf("%.3f",mark->num);free(mark);}
else
{printf("%c",mark->op);free(mark);}
}
while
(1);
printf("\n");
///////////////////////////////////////////
//////////////后缀表达式的计算/////////////
///////////////////////////////////////////
floatx,y;
mark=dequeue(formula4);
while(mark->num!
=12345)//若队不为空
{
if(mark->w==0)
{
formula3=push(formula3,0,mark->num,0);free(mark);
}
else
{
sign=pop(formula3);y=sign->num;formula3=sign->q;free(sign);//两次取操作数并交换次序
sign=pop(formula3);x=sign->num;formula3=sign->q;free(sign);
switch(mark->op)//计算周缀表达式的值
{
case'+':
formula3=push(formula3,0,x+y,0);break;
case'-':
formula3=push(formula3,0,x-y,0);break;
case'*':
formula3=push(formula3,0,x*y,0);break;
case'/':
formula3=push(formula3,0,x/y,0);break;
default:
printf("ERROR!
!
!
\n");ret
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 中缀 表达式 转换 后缀 算法 计算 实现