C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现Word文档下载推荐.docx
《C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《C#中缀表达式转换为后缀表达式算法及后缀表达式计算算法的实现Word文档下载推荐.docx(21页珍藏版)》请在冰豆网上搜索。
}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;
rchild=NULL;
ltag=0;
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]的两个孩子已经处理完毕,出队列
//输入下一个字符
returnroot;
//返回根指针
}
//关于建立新树:
输入处理(关于完全二叉树)
//中序遍历
voidinorder(bitree*t)
if(t)//二叉树非空
inorder(t->
lchild);
//中序遍历t的左子树
printf("
%c"
t->
data);
//访问结点t
rchild);
//中序遍历t的右子树
//前序遍历
voidpreorder(bitree*t)
preorder(t->
//后序遍历
voidpostorder(bitree*t)
postorder(t->
voidinthread(bitree*p)//将二叉树p中序线索化,线索标志初值为0
if(p!
=NULL)
inthread(p->
//左子树线索化
if(p->
lchild==NULL)p->
ltag=1;
//建立左线索标志
if(p->
rchild==NULL)p->
rtag=1;
//建立右线索标志
if(pre!
{
if(pre->
rtag==1)//p无右子树
pre->
rchild=p;
//右线索p->
rchild为p
ltag==1)//p无左子树
lchild=pre;
//左线索p->
lchild为pre
}
pre=p;
inthread(p->
//右子树线索化
//在中序线索树中找结点*p的中序后继
bitree*inordernext(bitree*p)
bitree*q;
rtag==1)//p右子树为空
return(p->
//p->
rchild是右线索,指向p的后继
else//p的右子树非空
q=p->
rchild;
//从p的右孩子开始查找
while(q->
ltag==0)//当q不是左下结点时,继续查找
q=q->
lchild;
return(q);
//遍历中序线索二叉树p
voidtravereinthread(bitree*p)
=NULL)//非空树
while(p->
ltag==0)//找中序序列的开始结点
p=p->
do
p->
//访问结点p
p=inordernext(p);
//找p的中序后继结点
}while(p!
=NULL);
voidmain()
bitree*p;
inta=0;
\t\t**********************************************\n"
\t\t************二叉树************\n"
\t\t**********************************************\n\n"
p=creatree();
//创建二叉树
\n"
\t\t二叉树的前序遍历结果为:
\t\t"
preorder(p);
\t\t二叉树的中序遍历结果为:
inorder(p);
\t\t二叉树的后序遍历结果为:
postorder(p);
inthread(p);
//中序线索化
\t\t二叉树的中序线索化遍历结果为:
travereinthread(p);
//中序线索话遍历
getch();
//在结点p、p的右子树之间插入新结点q
insertright(bithptr*p,bithptr*q)
bithptr*s;
s=inordernext(p);
//查找p的原中序后继结点
q->
//建立q的左线索标志
lchild=p;
//q的中序前趋为p
rtag=p->
rtag;
rchild=p->
//q的右子树或右线索等于原p的右子树或右线索
p-ratag=0;
p->
rchild=q;
//新结点q作为p的右孩子
if((s!
=NULL)&
(s->
ltag==1))
lchild=q;
//结点s的左链是线索,s的前趋是p
math.h>
typedefstructnode//定义栈结构体类型
booln;
//标志操作数和操作符
charoperate;
//操作符
floatnum;
//操作数
structnode*next;
}stack;
structchangenum//临时变量
boolw;
charop;
stack*q;
};
stack*InitStack()//初始化堆栈
stack*S;
S=(stack*)malloc(sizeof(stack));
S->
n=0;
num=0;
operate=0;
next=NULL;
returnS;
stack*push(stack*top,booln,floatnum,charoperate)//进栈函数
stack*p;
p=(stack*)malloc(sizeof(stack));
//生成新节点
if(n==0)//进栈的为浮点数
p->
operate=NULL;
num=num;
if(n==1)//进栈的为操作符
n=1;
operate=operate;
num=NULL;
next=top;
top=p;
returnp;
changenum*pop(stack*top)//退栈函数
changenum*sp;
sp=(changenum*)malloc(sizeof(changenum));
if(top->
next==NULL){printf("
underflow!
returnNULL;
}//栈下溢
else//退栈操作
p=top;
top=top->
next;
sp->
q=top;
num=p->
num;
op=p->
operate;
w=0;
returnsp;
//*******************************************
//****************栈定义及操作***************
//后缀表达式的存储
typedefstructnode2
booln;
floatnum;
//操作数
charoperate;
structnode2*front,*rear,*next;
//队头队尾指针
}squeue;
//定义队列类型
squeue*q;
squeue*InitQueue()//初始化队列
{
squeue*Q;
Q=(squeue*)malloc(sizeof(squeue));
Q->
front=Q;
num=12345;
front->
rear=Q;
returnQ;
voidenqueue(squeue*q,booln,floatnumber,charop)//入队操作
if(op=='
)'
);
rear->
next=(squeue*)malloc(sizeof(squeue));
rear=q->
if(n==0)
num=number;
if(n==1)
operate=op;
changenum*dequeue(squeue*q)//出队操作
squeue*s;
changenum*sp;
sp=(changenum*)malloc(sizeof(changenum));
if(q->
next==NULL){sp->
num=q->
w=q->
n;
else
{
s=q->
next=s->
sp->
w=s->
num=s->
op=s->
returnsp;
//****************队定义及操作***************
//实现表达式的临时存储
intpriority(charch)//操作符及操作数优先级判断
switch(ch)
case'
+'
:
-'
return2;
*'
/'
return3;
('
return1;
return4;
case'
'
return10;
.'
0'
1'
2'
3'
4'
5'
6'
7'
8'
9'
return0;
default:
printf("
ERROR!
"
return5;
changenum*getlist(charch)//将字符数组转为float类型变量
if(priority(ch)==0)
intp=1;
floatsum=0,point=0;
chara[40];
intm=0;
intn=1;
for(inti=0;
i<
=39;
i++)
a[i]=0;
priority(ch)==0)
a[m]=ch;
sum=sum*10+(a[m]-'
m++;
//整数部分
if(ch=='
)
while(priority(ch)==0)//小数部分处理
a[m+n]=ch;
point=point*10+(a[m+n]-'
p=p*10;
n++;
sum=sum+point/p;
//转为浮点数
num=sum;
op=ch;
w=1;
num=100;
op=100;
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,'
请输入表达式以#结束:
do
mark=getlist(ch);
i=mark->
w;
if(i==0)
enqueue(formula2,0,mark->
num,0);
enqueue(formula4,0,mark->
ch=mark->
op;
free(mark);
//将操作数入队
switch(ch)//操作符处理
{
:
formula1=push(formula1,1,0,ch);
break;
//将做括号压入栈S
if(formula1->
operate=='
){printf("
括号不匹配!
!
return1;
else
{
do
sign=pop(formula1);
formula1=sign->
q;
a=sign->
if(a=='
)break;
elseif(priority(a)==4);
else{enqueue(formula2,1,0,a);
enqueue(formula4,1,0,a);
}
while(a!
if(a=='
while(formula1->
operate!
&
formula1->
priority(formula1->
operate)>
=priority(ch))
{
sign=pop(formula1);
enqueue(formula2,1,0,sign->
op);
enqueue(formula4,1,0,sign->
}
case'
default:
}
//表达式扫描结束条件
//表达式扫描结束后若栈中还有元素则依次弹出输入的后缀表达式中
if(sign->
op=='
else{enqueue(formula2,1,0,sign->
enqueue(formula4,1,0,sign->
后缀表达式为:
do//后缀表达式的输出
mark=dequeue(formula2);
if(mark->
num==12345)break;
w==0)
{printf("
%.3f"
mark->
num);
%c"
while
(1);
///////////////////////////////////////////
//////////////后缀表达式的计算/////////////
floatx,y;
mark=dequeue(formula4);
while(mark->
num!
=12345)//若队不为空
if(mark->
w==0)
formula3=push(formula3,0,mark->
sign=pop(formula3);
y=sign->
formula3=sign->
free(sign);
//两次取操作数并交换次序
x=sign->
switch(mark->
op)//计算周缀表达式的值
formula3=push(formula3,0,x+y,0);
break;
formula3=push(formula3,0,x-y,0);
formula3=push(formula3,0,x*y,0);
formula3=push(formula3,0,x/y,0);
default:
ret