实验三实验报告Word文档下载推荐.docx
《实验三实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《实验三实验报告Word文档下载推荐.docx(18页珍藏版)》请在冰豆网上搜索。
二叉树T已经存在。
销毁T。
Value(&
计算出T所表示的四则运算表达式的值并返回。
}ADTBineryTree
顺序栈的抽象数据类型定义
ADTStack{
具有相同类型及后进先出特性的数据元素集合。
相邻数据元素具有前去和后继关系。
基本操作:
InitStack(&
无
构造一个空栈S。
DestroyStack(&
栈S已经存在。
销毁S。
StackLength(&
返回S中元素个数。
GetTop(S,&
e)
栈S已经存在且非空。
用e返回S的栈顶元素。
Push(&
S,e)
插入元素e为S的新栈顶元素。
Pop(&
初始条件:
删除S的栈顶元素,并用e返回其值。
}ADTStack
字符串的抽象数据类型定义
ADTString{
具有字符类型的数据元素集合。
相邻数据元素具有前驱和后继关系。
StrLength(S)
串S已经存在。
返回S的元素个数。
StrNeg(S,F)
串S已经存在且非空。
求S的逆序并将结果保存在串F中。
}ADTString
本程序包含四个模块:
主程序模块;
二叉树单元模块(实现二叉树的抽象数据类型,包括结点和指针的定义);
顺序栈单元模块(实现顺序栈的抽象数据类型,包含结点和指针的定义);
字符串单元模块(实现字符串的抽象数据类型)。
四个模块之间调用关系为主程序模块二叉树模块,二叉树模块调用顺序栈模块。
详细设计
顺序栈类型。
#defineStack_Size100
typedefstruct{
charelem[Stack_Size];
inttop;
}SqStack
基本操作实现的伪代码算法如下:
voidInitStack(SqStack&
S){//初始化顺序栈
S.elem=newElemType[Stack_Size];
if(!
S.elem)Error("
Overflow!
"
);
S.top=-1;
}
viodPush(SqStack&
S,charc){//顺序栈压栈
if(S.top==(Stack_Size-1))Error("
StackOverflow!
S.elem[++S.top]=c;
ElemTypePop(SqStack&
S){//顺序栈出栈
if(S.top==-1)Error("
StackEmpty!
returnS.elem[S.top--];
intStackLength(SqStack&
S){//求顺序栈长度
return(S.top+1);
GetTop(SqStack&
S,chare){//取栈顶元素
e=S.elem[top];
字符串类型
typedefstruct{//动态顺序串
char*ch;
intlength;
}String
基本操作实现的伪代码算法如下:
intStrLength(&
S){//求串长
returnS.length;
voidStrNeg(&
S,&
F){//求逆序串
if(!
S.length)error(“StringEmpty!
”);
for(i=0;
i<
length;
i++)
F.ch[i]=S.ch[length-1-i];
二叉树类型。
typedefstructTNode{//二叉树结点
uniondata{charoptr;
//运算符
intopnd;
};
//操作数
structTNode*lchild,*rchild
}TNode
typedefTNode*BiTree//二叉树指针
intPrecedence(charopr){//判断运算符级别函数;
其中*/的级别为2,+-的级别为1;
intlevel;
switch(opr){
case'
+'
:
case'
-'
return
(1);
break;
*'
/'
return
(2);
('
)'
#'
default:
return(0);
boolIsOperator(charopr){//判断输入串中的字符是不是合法操作符
if(op=='
||op=='
)
returntrue;
else
returnfalse;
stringConvert(string&
Str){//将一个中缀串转换为后缀串,
stringOutput;
//输出串
SqStackS;
for(inti=S.length-1;
i>
=0;
i--){//对输入串逆序扫描
if(Str.ch[i]>
=48&
&
Str.ch[i]<
=57){
Output.ch[i]=Str.ch[i];
//假如是操作数,把它添加到输出串中。
Output.length++;
if(Str.ch[i]=='
)//假如是右括号,将它压栈。
Push(S,Str.ch[i]);
while(IsOperator(s[i])){//如果是运算符
if(top==0||GetTop(S)=='
||Precedence(Str.ch[i])>
=Precedence(GetTop(S))){
Push(S,Str.ch[i]);
else{Pop(S,e);
Output.ch[i]=e;
Output.length++;
}}
){//假如是左括号,栈中运算符逐个出栈并输出,直到遇到右括号。
右括号出栈并丢弃。
while(GetTop(S)!
='
){
Output.ch[i]=Pop(S);
}
while(S.top!
=-1){//假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。
Output.ch=Output.ch--;
Output.ch=Pop(S);
returnoutput;
}
voidCreatBiTree(&
S){//由中缀表达式生成表达式二叉树
StringF;
SqStackSq;
//用以存放生成的二叉树结点
InitStack(Sq);
F=Convert(S);
//求得S的前缀表达式
for(i=F.length-1;
i--){
If(!
IsOperator(F.ch[i])){
T=newTNode;
T->
data=F.ch[i];
lchild=NULL;
rchild=NULL;
Push(Sq,T)}
else{
lchild=Pop(Sq);
rchild=Pop(Sq);
Push(Sq,T);
intCalc(inta,charopr,intb){//计算
switch(opr){
case'
returna+b;
returna-b;
returna*b;
returna/b;
intValue(TNode*T){
if(T->
lchild==NULL&
T->
rchild==NULL)
returnT->
data;
returnCalc(Value(T->
lchild),T->
data,Value(T->
rchild));
};
主函数伪码算法。
voidmain(){
Face();
//输出界面及相关信息
do{
cout<
<
”Pleaseinputanexpression:
”<
endl;
cin>
>
Str;
JudgeExp(S);
//判断输入的表达式是否合法。
T=CreatBiTree(S);
N=Value(T);
cout<
”Thevalueofthisexpressionis”<
N<
”Todoanothercalculation?
[Y/N]”;
cin>
e;
if(e==’y’)flag=1;
elseflag=0;
}while(flag)
}//main
测试结果
附录(带注释的源程序)
//****************************CStack.h******************************//
#include<
iostream>
usingnamespacestd;
typedefstruct
{//字符类型顺序栈
}CStack
voidInitCStack(&
{//初始化顺序栈
S.elem=newchar[Stack_Size];
if(!
S.top=-1;
voidPush_C(CStack&
S,chare)
{//压栈
if(S.top==(Stack_Size-1))Error("
S.elem[++S.top]=e;
charPop_C(CStack&
{//出栈
if(S.top==-1)Error("
returnS.elem[top--];
charGetTop(&
{//取栈顶元素
returnS.elem[top];
intCStackLength(&
{//求栈中元素个数
returntop+1;
//****************************TStack.h******************************//
#include"
Tree.h"
{//二叉树结点类型顺序栈
TNodeelem[Stack_Size];
}TStack
voidInitTStack(&
voidPush_T(TStack&
S,TNodeT)
S.elem[++S.top]=T;
TNodePop_T(TStack&
//****************************String.h******************************//
typedefstruct//动态顺序串
{
intlen;
SrtingStrNeg(&
Str)//求逆序串
F.ch[i]=Str.ch[Str.len-1-i];
returnF
intStrLen(&
Str)//求串长
inti;
Str.ch[i]!
\0'
;
)i++;
returni;
//****************************Tree.h******************************//
String.h"
CStack.h"
TStack.h"
{//二叉树结点
uniondata
{//数据域
charopr;
intopn;
//运算数
structTNode*lchid,*rchild;
//指针域
typedefTNode*BiTree;
//二叉树头结点
intPrecedence(charopr)
{//判断运算符级别函数;
switch(opr)
{
return1;
return2;
return0;
boolIsOperator(charopr)
{//判断输入串中的字符是不是合法操作符
if(op=='
returntrue;
StringConvert(String&
Str)//将一个中缀串转换为后缀串
StringOutput;
//输出串
Output.len=0;
CStackS;
InitCStack(S);
Str.len=StrLen(Str);
//求的输入的串长
for(i=Str.len-1;
i--)//对输入串逆序扫描
if(Str.ch[i]>
=48&
Str.ch[i]<
=57)//假如是操作数,把它添加到输出串中。
Output.ch[Str.len-1-i]=Str.ch[i];
Output.len++;
)//假如是右括号,将它压栈。
Push_C(S,Str.ch[i]);
while(IsOperator(Str.ch[i]))//如果是运算符
if(S.top==0||GetTop(S)=='
=Precedence(GetTop(S)))
Output.ch[Str.len-1-i]=Pop_C(S);
)//假如是左括号,栈中运算符逐个出栈并输出
{//直到遇到右括号。
while(GetTop(S)!
)
while(S.top!
=-1)//假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。
Output.ch[++Output.len-1]=Pop_C(S);
returnStrNeg(Output);
//输出Output的逆序即为所求前缀表达式
Str)//由中缀表达式生成表达式二叉树
TStackS;
InitTStack(S);
F=Convert(Str);
for(i=F.len-1;
i--)
if(!
IsOperator(F.ch[i]))
Push_T(S,T)
lchild=Pop_T(S);
rchild=Pop_T(S);
Push_T(S,T);
intCalc(inta,charopr,intb)//计算
switch(opr)
intValue(TNode*T)//求表达式二叉树的值
//****************************JudgeExp.h******************************//
boolJudegExp(StringExp)//此函数验证式子是否正确,即是否符合运算规则。
charcheck;
interror=0;
intlb=0;
intrb=0;
if(StrLen(Exp)==1&
Exp.ch[0]!
elseif((IsOperator(Exp.ch[0])&
||IsOperator(Exp.ch[StrLen(Exp)-1]))&
&
Exp.ch[StrLen(Exp)-1]!
)//此处若不加,在遇到某些式子时,会出现非法操作。
for(intm=0;
m<
StrLen(Exp);
m++)
check=Exp.ch[m];
if(m==0&
check=='
(IsDigit(Exp.ch[1])!
=0||Exp.ch[1]=='
))check=Exp.ch[++m];
if(IsOperand(check));
//如果是数字,跳过,不管。
elseif(IsOperator(check))
if(check=='
rb++;
if(IsOperator(Exp.ch[m+1])&
(Exp.ch[m+1]=='
||Exp.ch[m+1]=='
||Exp.