数据结构课程设计报告.docx
- 文档编号:6937470
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:28
- 大小:91.22KB
数据结构课程设计报告.docx
《数据结构课程设计报告.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告.docx(28页珍藏版)》请在冰豆网上搜索。
数据结构课程设计报告
<<数据结构>>
课程设计报告
题目5.7表达式类型的实现
2008年7月
表达式类型的实现
一、存储结构定义
本程序在关于二叉树方面使用二叉链表进行存储,在关于栈方面使用顺序存储。
抽象数据类型如下:
抽象数据类型
ADTBinaryTree{
数据对象D:
D是具有相同特性的数据元素的集合。
数据关系R;
若D=Φ,则R=Φ,称BinaryTree为空二叉树;
若D不等于Φ,则R={H},H是如下二元关系:
(1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱;
(2)若D-{root}不等于Φ,则存在D-{root}={D1,Dr},且D1并Dr=Φ;
(3)若D1不得已Φ,则D1中存在唯一的元素x1,
(4)(D1,{H1})是一颗符合本定义的二叉树,称为根的左子树,(Dr,{Hr})是一颗符合本定义的二叉树,称为根的右子树。
基本操作P:
InitBiTree(&T);
操作结果:
构造空二叉树T。
DestroyBiTree(&T);
初始条件:
二叉树T存在。
操作结果:
销毁二叉树T。
PreOrderTraverse(T,Visit());
初始条件:
二叉树T存在,Visit是对结点操作的应用函数。
操作结果:
先序遍历T,对美国结点调用函数Visit一次且仅一次。
一旦visit()失败,则操作失败。
}ADTBinaryTree
ADTStack{
数据对象:
D={ai|ai属于ElemSet,i=1,2,……,n,n>=0}
数据关系:
R1={
约定an端为栈顶,a1端为栈底。
基本操作:
InitStack(&S)
操作结果:
构造一个空栈S。
DestroyStack(&S)
初始条件:
栈S已存在。
操作结果:
栈S被销毁。
GetTop(S,&e)
初始条件:
栈S已存在且非空。
操作结果:
用e返回S的栈顶元素。
Push(&S,e)
初始条件:
栈S已存在。
操作结果:
插入元素e为新的栈顶元素。
Pop(&S,&e)
初始条件:
栈S已存在且非空。
操作结果:
删除S的栈顶元素,并用e返回其值。
}ADTStack
程序的头文件如下:
#include
#include"iostream.h"
#include"stdio.h"
#include"malloc.h"
#defineTRUE1
#defineFALSE0
#defineOK1
#defineOVERFLOW-1
#defineERROR0
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
///数据类型定义
typedefintStatus;
typedefstructBiTNode
{
inttdata;//放int数据,当有数字时,data='&',用'&'标志结点放的是数字
chardata;//放字母和运算符号
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
///栈的数据类型定义
typedefcharSElemType;
typedefstruct//用于前缀表达式建立二叉树时的栈类型。
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefstruct//用于原表达式建立二叉树时的栈类型。
{
BiTree*base;
BiTree*top;
intstacksize;
}SBStack;
SBStackS1;
SqStackS;//借用该栈来实现阿拉伯数字的输入
SqStackPTR;
////栈的函数声明
voidMerger();
voidoutput();
voidyuanput();
StatusIntiStack(SqStack&S);
intStackLength(SqStackS);
StatusPush(SqStack&S,chare);
charPop(SqStack&S);
StatusDestroyStack(SqStack&S);
StatusGetTop(SqStackS,char&e);
StatusIntiSBtack(SBStack&S);
StatusBPush(SBStack&S,BiTNode*e);
BiTreeBPop(SBStack&S);
charGetTop(SqStackS);
charbPop(SqStack&S,char&e);
///////////////////////////////
voidinput();//输入表达式
StatusIntiBiTree(BiTree&T);//二叉树的初始化
StatusDestroyBiTree(BiTree&T);//二叉树的销毁
StatusCreateBiTree(BiTree&T);//前缀表达式建立二叉树
voidCrtExptree(BiTree&T);//原表达式建立二叉树
voidCrtNode(BiTree&T,charch);
voidCrtSubtree(BiTree&T,charc);
StatusPreOrderTraverse(BiTreeT,Status(*Visit)(BiTNode*e));//先序遍历
intpow10(intb);//10的b方
//////////////////////////
StatusPrintBiTree(BiTreee);//树的先序输出
StatusMergeConst(BiTree&T);//合并(一次)
StatusMergeConst5(BiTree&T);//设五次内能合并完整
StatusAssign(BiTree&T);//变量附值
Statusassignnew(BiTree&T,charb,inta);
StatusValue(BiTree&T);//符值后求值
BiTreeCompoundExpr(charP,BiTreeT1,BiTreeT2);//复合表达式
voidwriteExpr(BiTreeT);//表达式的正确输出(有带括号的中缀式)
intIn(charc,char*op);//比较字符是否为运算符,是则返回1,否则0
intPrecedel(charop,charc);//比较运算符的优先级
intPreceder(charop,charc);//比较运算符的优先级
intPrecede1(charop,charc);//比较运算符的优先级
intIn1(charc,char*op);//比较字符是否为运算符,是则返回1,否则0
////////////////////////////
charin[100];//假设表达式最多有100个字符,“#”表示输入完毕
inta=0;//定义该全局变量来一个一个地初始化树
///////////////////
charOP[5]={'+','-','*','/','^'};
charOP1[8]={'+','-','*','/','^','(','#',')'};//运算符
intprecedel[][5]={{0,0,0,0,0},{0,0,0,0,0},{1,1,0,0,1},{1,1,0,0,1},{1,1,1,1,1}};//检查运算符排序方法
intpreceder[][5]={{0,0,0,0,0},{1,1,0,0,0},{1,1,0,0,1},{1,1,1,1,1},{1,1,1,1,1}};
intprecede1[][7]={{1,1,0,0,0,0,1},{1,1,0,0,0,0,1},{1,1,1,1,0,0,1},{1,1,1,1,0,0,1},{1,1,1,1,1,0,1},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}};
BiTreet,t1,t2,t3;
二.算法设计:
1.算法思路:
(1)当输入前缀表达式时,使用数组存储输入的表达式,使用栈暂时性寄存表达式中的数值,调用函数StatusCreateBiTree(BiTree&T)建立二叉树。
(2)当输入原表达式时,使用数组存储输入的表达式,使用栈SqStackPTR存储运算符,栈SBStackS1用于实现叶子结点的存储。
把表达式变成后缀表达式,在此过程中建立二叉树。
(3)通过反复调用函数StatusMergeConst(BiTree&T),用先序遍历实现表达式中常量的合并。
(4)用中序遍历实现表达式的输出,期间,调用函数intIn(charc,char*op)和intPrecedel(charop,charc),判断是否需要输出括号。
2.数据实现
(1)数据存储数据的输入由函数input()实现并存储。
使用栈作为过渡,使用二叉链表作为建成的二叉树的存储。
(2)数据的逻辑结构
///数据类型定义
typedefintStatus;
typedefstructBiTNode
{
inttdata;//放int数据,当有数字时,data='&',用'&'标志结点放的是数字
chardata;//放字母和运算符号
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
///栈的数据类型定义
typedefcharSElemType;
typedefstruct
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefstruct
{
BiTree*base;
BiTree*top;
intstacksize;
}SBStack;
(3)数据的存储结构。
使用顺序栈,数组,二叉链表进行存储。
(4)主程序
voidmain(){
初始化;
while
(1)
{输出;
switch(i){
case1:
前缀式输入,求值;break;
case2:
复合表达式;break;
case3:
表达式原形式输入;break;
case4:
退出;
}
}
(5)调用关系
本程序有四个模块,调用关系为:
主程序模块
主程序模块
3.详细设计
头文件
#include"sheji.h"
主函数
voidmain()
{chark;
inti;
IntiBiTree(t);
t2=t;
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★\n");
printf("\t\t★------------------------------------------------------------★\n");
printf("\t\t★表达式类型的实现★\n");
printf("\t\t★★\n");
printf("\t\t★06级计算机科学与技术(9)班★\n");
printf("\t\t★★\n");
printf("\t\t★★\n");
printf("\t\t★------------------------------------------------------------★\n");
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★\n");
printf("是否进入该系统?
(输入y进入)\n");
k=getchar();
getchar();
if(k=='Y'||k=='y')
system("cls");
elseexit(OVERFLOW);
while
(1)
{t=t2;
IntiStack(S);//初始化
printf("\t\t★★★★★★★★表达式类型的实现★★★★★★★★\n");
printf("\t\t★请选择程序功能:
★\n");
printf("\t\t★★\n");
printf("\t\t★1.前缀式输入,求值★\n");
printf("\t\t★2.复合表达式★\n");
printf("\t\t★3.表达式原书写形式输入,求值★\n");
printf("\t\t★4.退出★\n");
printf("\t\t★★\n");
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★★★\n");
printf("请输入您所要操作的序号:
");
scanf("%d",&i);
getchar();
system("cls");
switch(i)
{
case1:
output();break;
case2:
Merger();break;
case3:
yuanput();break;
case4:
exit(OVERFLOW);
}
}
}
voidMerger()//复合表达式
{BiTreeT1,T2,Te;
IntiBiTree(T1);
IntiBiTree(T2);
IntiBiTree(Te);//初始化
printf("\t\t★★★★★★★★表达式类型的实现★★★★★★★★★\n");
printf("\t\t★---------------------------------------------------------------------★\n");
printf("\t\t★请以“#”表示表达式结束,以“$”隔开两个数字。
★\n");
printf("\t\t★---------------------------------------------------------------------★\n");
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★★★★\n");
printf("\t\t\n");
charP;
printf("\t\t★★★★★★★★构造新的复合表达式★★★★★★★★\n");
printf("\t\t\n");
printf("\t\t★请输入要复合的符号:
");
scanf("%c",&P);
printf("\t\t★请输入要复合的第一个表达式:
");
a=0;
input();//应从in[100]的0位开始
CreateBiTree(T1);
printf("\t\t★请输入要复合的第二个表达式:
");
a=0;//应从in[100]的0位开始
input();
CreateBiTree(T2);
Te=CompoundExpr(P,T1,T2);//调用复合函数
printf("\t\t★两个表达式复合后的中缀表达式为:
");
writeExpr(Te);//复合后中缀输出
printf("\n");
printf("按任意键返回。
\n");
getchar();
getchar();
system("cls");
DestroyBiTree(T1);
DestroyBiTree(T2);
DestroyBiTree(Te);
DestroyStack(S);
}
voidoutput()//前缀表达式输入,建树,输出,合并
{
BiTreeT;
IntiBiTree(T);
printf("\t\t★★★★★★★★表达式类型的实现★★★★★★★★★\n");
printf("\t\t★---------------------------------------------------------------------★\n");
printf("\t\t★请以“#”表示表达式结束,以“$”隔开两个数字。
★\n");
printf("\t\t★---------------------------------------------------------------------★\n");
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★★★★\n");
printf("\t\t\n");
printf("\t\t★请输入表达式的前缀表达式:
");
input();//调用输入函数
CreateBiTree(T);//调用表达式建立二叉树函数
printf("\t\t★您的输入为:
");
PreOrderTraverse(T,PrintBiTree);
printf("\n");
printf("\t\t★表达式的中缀式为:
");
writeExpr(T);//调用中序输出函数
printf("\n");
printf("\t\t★常量合并后为:
");//若表达式里有可以合并的数字,则调用后可以看到合并的结果
MergeConst5(T);
writeExpr(T);
printf("\n");
t=T;
Assign(T);//调用附值函数给每个变量附值
printf("\t\t★附值后的结果为:
");
Value(t);//调用求值函数
printf("按任意键返回。
\n");
getchar();
getchar();
system("cls");
DestroyBiTree(T);
DestroyStack(S);
}
voidyuanput()//表达式原书写形式输入,建树,输出
{
BiTreeT3;
IntiBiTree(T3);
printf("\t\t★★★★★★★★表达式类型的实现★★★★★★★★★\n");
printf("\t\t★----------------------------------------------★\n");
printf("\t\t★请以“#”表示表达式结束,以“$”隔开两个数字。
★\n");
printf("\t\t★----------------------------------------------★\n");
printf("\t\t★★★★★★★★★★★★★★★★★★★★★★★★★\n");
printf("\t\t\n");
printf("\t\t★请输入表达式的的正确书写形式:
");
input();//调用输入函数
CrtExptree(T3);//调用表达式建立二叉树函数
printf("\t\t★表达式的前缀式为:
");
PreOrderTraverse(T3,PrintBiTree);
printf("\n");
printf("\t\t★表达式的中缀式为:
");
writeExpr(T3);//调用中序输出函数
printf("\n");
printf("按任意键返回。
\n");
getchar();
system("cls");
DestroyBiTree(T3);
DestroyStack(S);
}
///////////////函数定义
StatusIntiBiTree(BiTree&T)
{
T=NULL;
returnOK;
}
StatusDestroyBiTree(BiTree&T)
{
free(T);
T=NULL;
returnOK;
}
voidinput()//输入表达式的函数
{
chard='a';
for(intb=0;d!
='#';b++)
{
cin>>d;
in[b]=d;//附给in[100]数组
}
}
StatusCreateBiTree(BiTree&T)//表达式建立二叉树
{
while(in[a]!
='#')//以#结束
{
if(in[a]=='-'||in[a]=='+'||in[a]=='*'||in[a]=='/'||in[a]=='^')//当字符为运算符时
{
if(!
(T=(BiTNode*)malloc(sizeof(BiTNode))))returnERROR;
T->data=in[a];
a++;
CreateBiTree(T->lchild);//运算符需要建立它的左右孩子
CreateBiTree(T->rchild);
returnOK;
}
else
{
if(in[a]=='0'||in[a]=='1'||in[a]=='2'||in[a]=='3'||in[a]=='4'||
in[a]=='5'||in[a]=='6'||in[a]=='7'||in[a]=='8'||in[a]=='9')//当字符是阿拉伯数字时
{
Push(S,in[a]);//建一个栈来放阿拉伯数字
if(in[a+1]!
='0'&&in[a+1]!
='1'&&in[a+1]!
='2'&&in[a+1]!
='3'&&in[a+1]!
='4'&&
in[a+1]!
='5'&&in[a+1]!
='6'&&in[a+1]!
='7'&&in[a+1]!
='8'&&in[a+1]!
='9')//如果下一个不是阿拉伯数字
{
if(!
(T=(BiTNode*)malloc(sizeof(BiTNode))))returnERROR;
else
{
T->data='&';//标志表示放的是int型的数据
intlength=StackLength(S);intsum=0;
for(;S.base!
=S.top;)
{//把栈里的阿拉伯数字转换为int型的数据放到T->tdata,并T->data='&'来标志结点放的是数字
chard=Pop(S);
inth=length-(S.top-S.base+1);
intk=pow10(h);
sum+=(d-'0')*k;
}
T->tdata=sum;
T->lchild=T->rchild=NULL;
if(in[a+1]=='$')
a=a+2;
else
a++;
returnOK;
}
}
elsea++;//a++时in[100]的数组一个一个往后移动
}
else
{//当字符是字母时,直接T->data等于字母,并初始化T->tdata=0。
if(!
(T=(BiTNode*)malloc(sizeof(BiTNode))))returnERROR;
T->data=in[a];
T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告