数据结构大实验1报告副本Word文档格式.docx
《数据结构大实验1报告副本Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构大实验1报告副本Word文档格式.docx(27页珍藏版)》请在冰豆网上搜索。
输入的表达式会先存储进链表中再利用函数对栈和队列进行操作。
/*定义字符类型的链表*/
typedefstructlnode
{
chardata;
structlnode*next;
}lnode,*linklist;
/*定义字符类型的栈*/
typedefstructstack
structstack*next;
}stack,*linkstack;
/*定义字符类型的队*/
typedefstructqnode
structqnode*next;
}qnode,*queueptr;
typedefstruct
queueptrfront;
queueptrrear;
}linkqueue;
(1)优先级判断函数:
getprecedence(chare)判断运算符的优先级,返回每个运算符对应的数值。
运算符之间的关系:
+(加)=-(减)<
*(乘)=/(除)=%(取余)<
^(次方)=!
(开方)
(2)中缀转为后缀:
算法基本思想:
顺序扫描中缀表达式,当读到数字时,直接将其送至输出队列中;
当读到运算符时,将栈中所有优先级高于或等于该运算符的运算符弹出,送至输出队列中,再将当前运算符入栈;
当读入左括号时,将其入运算符栈;
当读到右括号时,将栈中从栈顶到靠近栈顶的第一个左括号之间的所有运算符全部依次弹出,送至输出队列中,再删除栈中的左括号。
流程图:
Y
N
Y
表格解释:
中缀表达式到后缀表达式的转换过程示例
转换步骤
中缀表达式的读入
运算符栈
后缀表达式
初始
1+2*(3-1+2)-3#
#
空
1
+2*(3-1+2)-3#
1
2
2*(3-1+2)-3#
#+
3
*(3-1+2)-3#
#+
12
4
(3-1+2)-3#
#+*
5
3-1+2)-3#
#+*(
6
-1+2)-3#
123
7
1+2)-3#
#+*(-
8
+2)-3#
1231
9
2)-3#
#+*(+
1231-
10
)-3#
1231-2
11
-3#
1231-2+
12
3#
#-
1231-2+*+
13
1231-2+*+3
14
1231-2+*+3-
(3)后缀表达式的计算:
利用栈(操作数和运算结果栈)计算后缀表达式。
顺序扫描后缀表达式,当读到数字时,将其送至栈中;
当读到运算符θ时,将栈顶字符弹出,将其转换成对应的数值并赋给变量y,再将次栈顶字符弹出,将其转换成对应的数值,并赋给变量x,之后计算xθy,将运算结果转换成对应的数字字符送入栈中。
表1-2后缀表达式计算过程示例
计算步骤
后缀表达式的读入
231-2+*+3-
31-2+*+3-
1-2+*+3-
-2+*+3-
2+*+3-
122
+*+3-
1222
*+3-
124
+3-
18
3-
9
-
93
6
(3)中缀表达式就计算:
将中缀表达式通过中缀到后缀的转化函数转成后缀表达式并利用后缀表达式的求值函数来计算。
5.实现及测试:
(1)开始菜单
(2)中缀表达式转换成后缀表达式
(3)后缀表达式的计算
例子:
23+4*5-
(4)中缀表达式的计算
(2+3)*4-5
(5)括号匹配检测
(6)除法零的处理
(7)其他运算符
n次幂运算
开平方运算
取余运算
时间复杂度上中缀表达式转后缀O(n),后缀表达式计算O(n^2),这个实验加深了我对栈和队列的理解,让我感受到了数据结构的强大作用,增加了我的学习热情。
这个程序的不足之处有很多,没有实现可视化也没有实现小数之间的运算,程序的操作界面过于简陋,我已经尽力而为了,在今后的学习中我会努力学习这些知识,让自己的编程水平更上一层楼!
7.参考文献:
《数据结构与算法》严蔚敏著
XX文库
8.附录
#include<
iostream>
stdlib.h>
cstdlib>
math.h>
windows.h>
usingnamespacestd;
typedefstructstack//链栈的定义
typedefstructlnode//队的定义
voidinitstack(linkstack&
s)//初始化栈
s=NULL;
}
voidpush(linkstack&
s,charc)//入栈
linkstackp;
p=newstack;
p->
data=c;
next=s;
s=p;
charpop(linkstack&
s)//出栈
charc;
if(s==NULL)
{
cout<
<
"
栈为空"
endl;
exit(0);
}
c=s->
data;
p=s;
s=s->
next;
deletep;
returnc;
chargettop(linkstack&
s)//取栈顶
if(s!
=NULL)
returns->
typedefstructqnode//链队的定义
voidinitqueue(linkqueue&
q)//初始化队
q.front=q.rear=newqnode;
q.front->
next=NULL;
voidenqueue(linkqueue&
q,chare)//入队
queueptrp;
p=newqnode;
data=e;
q.rear->
next=p;
q.rear=p;
voiddequeue(linkqueueq)//出队并输出出队的值
{
qnode*p;
p=q.front->
while(p!
{
p->
data<
"
;
p=p->
voidcreate(linklist&
l)//输入函数并建立链表
linklistp,r;
l=newlnode;
r=l;
chara;
cout<
请输入表达式并以#结尾"
cin>
>
a;
while(a!
='
#'
)
p=newlnode;
data=a;
r->
r=p;
r->
voidjudge(linklist&
l)//判断函数,判断括号的匹配
linkstacks;
initstack(s);
linklistp;
p=l->
if(p->
data=='
('
{
c=p->
push(s,c);
}
elseif(p->
)'
&
s!
pop(s);
s==NULL)
cout<
匹配失败,右括号多了"
exit(0);
p=p->
括号匹配成功"
else
匹配失败,左括号多了"
intgetprecedence(chare)//得到操作符的优先级
switch(e)
case'
:
return0;
+'
return1;
-'
*'
return2;
/'
%'
^'
return3;
!
'
}
}
voidinqueue(linkqueue&
q)//将后缀表达式入队,用来传给计算函数
charx;
cout<
请输入后缀表达式(以#结束输入):
<
endl;
x;
while(x!
{
p=newqnode;
data=x;
p->
q.rear=p;
linkqueuechange(linklist&
l,linkstack&
s,linkqueueq)//中缀表达式转换成后缀表达式
initqueue(q);
chara,b,c;
push(s,'
);
//先把#压入栈作为一个标志
if((p->
data)>
0'
(p->
data)<
9'
)//碰到数字入队
enqueue(q,p->
data);
)//碰到左括号入栈
push(s,p->
)//碰到右括号就出栈一直到栈顶为左括号再将左括号出栈
while(gettop(s)!
a=pop(s);
enqueue(q,a);
pop(s);
//删除左括号
elseif(gettop(s)=='
)//碰到做括号入栈
||p->
while(getprecedence(gettop(s))>
=getprecedence(p->
data))//碰到运算符就将优先级大于等于自己的运算符出栈再将出栈的运算符入队,最后将自己入栈
b=pop(s);
enqueue(q,b);
push(s,p->
else//不是上述的情况证明输入了一个错误的元素
输入格式有误!
系统无法识别,请重新输入!
)//将栈中元素出栈直到栈顶为标志#
c=pop(s);
enqueue(q,c);
dequeue(q);
//出队并输出
returnq;
intevaluateexpression(linkqueueq)//后缀表达式计算
intx1,x2,temp;
if(p->
data>
)//碰到数字就-48将char型转成int型,并将结果入栈
temp=p->
data-48;
push(s,temp);
'
)//碰到空格就跳过
)//碰到加号就弹出两个操作数并相加,并将结果入栈
x1=pop(s);
x2=pop(s);
temp=x1+x2;
)//碰到减号就弹出两个操作数并相减,并将结果入栈
temp=x1-x2;
)//碰到乘号就弹出两个操作数并相乘,并将结果入栈
temp=x1*x2;
)//碰到除号就弹出两个操作数并相除,并将结果入栈
x1=pop(s);
if(x1!
=0)
temp=x2/x1;
next;
else
格式错误!
)//碰到次方就弹出两个操作数并做次方运算,并将结果入栈
temp=pow(x2,x1);
)//碰到开方号就弹出一个个操作数并开平方,并将结果入栈
temp=sqrt(x1);
)//碰到取余号就弹出两个操作数并取余,并将结果入栈
temp=x2%x1;
temp=pop(s);
//栈中最后剩下的元素就为最后运算的结果
returntemp;
voidmenu()//菜单函数
¥***************************************************************************¥"
简易计算器系统"
endl<
1.实现中缀表达式到后缀表达式的转换"
2.实现后缀表达式的计算"
3.实现中缀表达式的计算"
4.退出"
voidmain()//主函数
system("
colorF9"
//输出界面调色
intnum,ret;
menu();
linklistl;
请输入你要的选项:
while(num!
=4)
cin>
num;
switch(num)
case1:
system("
cls"
中缀表达式到后缀表达式的转换:
linkqueueq;
create(l);
judge(l);
后缀表达式为:
q=change(l,s,q);
cout<
pause"
break;
case2:
后缀表达式的计算"
输入新的后缀表达式"
linkqueuem;
initqueue(m);
inqueue(m);
ret=evaluateexpression(m);
后缀表达式计算的结果:
ret<
case3:
中缀表达式的计算"
请输入一个中缀表达式(以#作为结束符):
judge(l);
ret=evaluateexpression(q);
中缀表达式的计算结果:
case4:
感谢您使用本系统,再见!
default:
没有此菜单选项"
if(num!
system("
menu();
请继续输入你的选择: