数据结构课程设计报告 魏子涵100901120.docx
- 文档编号:29679987
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:26
- 大小:201.69KB
数据结构课程设计报告 魏子涵100901120.docx
《数据结构课程设计报告 魏子涵100901120.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告 魏子涵100901120.docx(26页珍藏版)》请在冰豆网上搜索。
数据结构课程设计报告魏子涵100901120
课题一运动会分数统计
一、任务:
参加运动会有n个学校,学校编号为1……n。
比赛分成m个男子项目和w个女子项目。
项目编号为男子1~m,女子m+1~m+w。
不同的项目取前五名或前三名积分;取前五名的积分分别为:
7、5、3、2、1,前三名的积分分别为:
5、3、2;哪些项目取前五名或前三名由学生自己设定。
(m<=20,n<=20)
二、功能要求:
(1)可以输入各个项目的前三名或前五名的成绩;
(2)能统计各学校总分;
(3)可以按学校编号、学校总分、男女团体总分排序输出;
(4)可以按学校编号查询学校某个项目的情况;
(5)可以按项目编号查询取得前三或前五名的学校。
三、需求分析
本演示程序中,每个运动项目信息包含运动项目名称、积分规则、学校排名,每个学校信息包括学校编号、学校名称、男生总分、女生总分、团体总分,系统通过录入是实现各种功能。
演示程序以用户和计算机的对话的方式执行,即在计算机终端上显示“提示信息”之后用户可在键盘上输入演示程序中规定的运算命令;相应的输入数据和运算结果显示在其后。
数据结构方面,录入信息采用线性表结构来录入和查找,功能主要通过排序来实现。
四.流程图
程序源代码
五.程序源代码
#include
#include
#include
#include
#definesize100
typedefstruct
{
inteventnum;//项目号
intschoolnum;//学校号
intscore;//得分成绩
}elemtype1;
typedefstruct
{
elemtype1school[size];
inttotal;//总记录数
intn;//学校数
intm;//男子项目数
intw;//女子项目数
}sqlist;
typedefstruct
{
intgrades;//学校分数
intsn;//学校号
}elemtype2;
typedefstruct
{
elemtype2add[size];
}slist;
voidcreat(sqlist*l)//输入成绩
{
inti;
printf("请先输入各项目获奖学校及成绩\n");
for(i=0;i
{
printf("请输入项目号,学校号及成绩");
scanf("%d%d%d",&l->school[i].eventnum,&l->school[i].schoolnum,&l->school[i].score);
}
}
voidschool_total_number(sqlist*l,slist*p)//算学校总分
{
inti,j;
for(i=1;i<=l->n;i++)//i代表学校号,用j遍历
{
p->add[i].grades=0;
p->add[i].sn=i;
for(j=0;j
{
if(i==l->school[j].schoolnum)
p->add[i].grades+=l->school[j].score;
}
printf("学校%d总分为%d\n",i,p->add[i].grades);
}
}
voidreorder1(sqlist*l,slist*p)//按学校编号排序输出
{
inti;
for(i=1;i<=l->n;i++)
printf("%d学校总分为%d\n",p->add[i].sn,p->add[i].grades);
}
voidboy_total_number(sqlist*l,slist*p)//计算男子团体总分
{
inti,j;
for(i=1;i<=l->n;i++)
{
p->add[i].grades=0;
p->add[i].sn=i;
for(j=0;j
{
if(i==l->school[j].schoolnum)
{
if(l->school[j].eventnum<=l->m)
p->add[i].grades+=l->school[j].score;
}
}
}
}
voidgirl_total_number(sqlist*l,slist*p)//计算女子团体总分
{
inti,j;
for(i=1;i<=l->n;i++)
{
p->add[i].grades=0;
p->add[i].sn=i;
for(j=0;j
{
if(i==l->school[j].schoolnum)
{
if(l->school[j].eventnum>l->m)
p->add[i].grades+=l->school[j].score;
}
}
}
}
voidreorder2(sqlist*l,slist*p)//按总分排序输出
{
inti,k;
elemtype2q;
for(i=1;i<=l->n;i++)//对第n个学校排序
{
if(p->add[i].grades
{
q=p->add[i];//交换i与i+1的值
p->add[i]=p->add[i+1];
p->add[i+1]=q;
}
}
for(k=1;k<=l->n;k++)
printf("%d学校总分为%d\t",p->add[k].sn,p->add[k].grades);
}
voidconsult1(sqlist*l)//按学校编号查某个项目的情况
{
inti,j,k;
printf("请输入项目号及学校号");
scanf("%d%d",&j,&i);
for(k=0;k
{
if(i==l->school[k].schoolnum&&j==l->school[k].eventnum)
printf("%d学校在%d项目成绩为%d",i,j,l->school[k].score);
}
}
voidconsult2(sqlist*l)//按项目编号查询学校的情况
{
inti,j;
printf("请输入查询的项目数\n");
scanf("%d",&i);
for(j=0;j
{
if(i==l->school[j].eventnum)
printf("%d学校取得成绩%d\n",l->school[j].schoolnum,l->school[j].score);
}
}
intselect()
{
intnumber;
printf("大学生运动会管理系统\n");
printf("统计学校总分
(1)\n");
printf("按学校编号排序输出
(2)\n");
printf("学校总分排序输出(3)\n");
printf("男团体总分排序输出(4)\n");
printf("女团体总分排序输出(5)\n");
printf("按学校编号查询学校某个项目的情况(6)\n");
printf("按项目编号查询取得前三或前五名的学校(7)\n");
printf("请选择\n");
scanf("%d",&number);
returnnumber;
}
voidmain()
{
inttotal,n,m,w;
sqlists,*l=&s;//必须要有s,d
printf("\n运动会管理系统\n");
printf("请输入总记录数,学校数,男子项目数,女子项目数");
scanf("%d%d%d%d",&total,&n,&m,&w);
l=(sqlist*)malloc(sizeof(sqlist));//动态分配
l->total=total;l->n=n;l->m=m;l->w=w;
{creat(l);}
for(;;)//必须要循环
{switch(select())
{
case1:
{system("cls");slistd,*p=&d;school_total_number(l,p);break;}
case2:
{
system("cls");slistd,*p=&d;
school_total_number(l,p);system("cls");
reorder1(l,p);break;}
case3:
{
system("cls");slistd,*p=&d;
school_total_number(l,p);system("cls");
reorder2(l,p);break;
}
case4:
{
system("cls");slistd,*p=&d;
boy_total_number(l,p);
reorder2(l,p);break;
}
case5:
{
system("cls");slistd,*p=&d;
girl_total_number(l,p);
reorder2(l,p);break;
}
case6:
{system("cls");consult1(l);break;}
case7:
{system("cls");consult2(l);break;}
}
}
}
六.程序运行结果
七、调试分析
(1)在进行分数排名操作时,无发显示正确的排名信息,主要原因是在利用冒泡排序时循环次数出现错误,修改后得到解决。
(2)各项目分数信息采用线性表,这样便于比较排序以及信息的输出显示。
八.用户手册
(1)演示程序的运行环境为MicrosoftVisualStudio6.0中的MicrosoftVisualC++6.0中运行。
(2)进入演示程序后即显示DOS形式的界面。
(3)首先录入运动项目数据,在选择需要进行的操作,根据输入的信息系统会自行输出所需结果。
(4)接受其他命令后即执行相应运算和显示相应结果。
课题三 迷宫问题求解
一、问题描述:
迷宫问题是取自心理学的一个古典实验。
实验中,把一只老鼠从一个没有顶的大盒子的门放入,在盒中设置了许多墙,对行进的方向形成了多处阻挡。
盒子仅仅有一个出口,在出口处放置了一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。
重复对老鼠进行上述实验,看老鼠能在多久找到出口。
二、问题分析:
迷宫问题是从入口处发顺某一方向向前探索,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止。
为了保证在任何位置上都能沿原路退回,显然需要用一个后进先出的结构来保存从入口到当前位置的路径。
因此,可以迷宫求解问题中应用“栈”结构来实现。
三、概要设计:
(1)存储结构:
采用数组来表示迷宫,可以利用“1”来表示通路,用“0”来表示墙壁,在探索迷宫的过程中利用栈结构。
(2)算法思路:
首先设定一个入口和出口,如果当前位置“可通”,则纳入“当前路径”,并继续朝“下一位置”探索(下一位置指当前位置四周4个方向(东南西北)上相邻的方块),并用“下一位置”代替“当前位置”,如此重复直至到达出口,如当前位置“不可通”,则顺着来向退回前一位置,然后朝着除原来方向之外的其他方向继续探索;如“当前位置”的四个方向均“不可通”,则应从“当前路径”上删除该位置。
假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”,由此,“记录路径”的操作即为“当前位置入栈”;从当前路径上删除前一通道块的操作即为“出栈”。
四、详细设计:
用一个字符类型的二维数组来表示迷宫,数组中每个元素取值“0”表示墙壁“1”表示通路。
迷宫的入口设在(1,1)处,出口设在(8,8)处。
走迷宫可模拟为一个探索过程:
没到一处,让它按东南西北的方向顺序探索下一个位置。
如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续探索:
如果某个方向走不通或已经到达过,则退回一步,在原来的位置上继续探索下一个位置。
每前进一步都要判断:
若前进到了出口处,则说明找到了一条通路,若退回到了入口处,则说明不存在通路。
五.源程序为代码:
#defineOVERFLOW-2
#defineERROR0
#defineNULL0
#definetrue1
#defineTRUE1
#definefalse0
#defineFALSE0
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#include
#include
/*
初始化迷宫,1表示通道,0表示墙
*/
intmaze[8][8]=
{
1,1,0,1,1,1,0,1,
1,1,0,1,1,1,0,1,
1,1,1,1,0,0,1,1,
1,0,0,0,1,1,1,1,
1,1,1,0,1,1,1,1,
1,0,1,1,1,0,1,1,
1,0,0,0,1,0,0,1,
0,1,1,1,1,1,1,1
};
//定义栈元素类型
typedefstructMStackElem
{
intx;//x坐标
inty;//y坐标
intval;//maze[x][y]的值
}MStackElem;
//定义栈
typedefstruct{
MStackElem*base;
MStackElem*top;
intstackSize;
}MStack;
voidinitStack(MStack*s)
{
s->base=(MStackElem*)malloc(STACK_INIT_SIZE*sizeof(MStackElem));
if(!
s->base)
exit(OVERFLOW);//存储分配失败
s->top=s->base;
s->stackSize=STACK_INIT_SIZE;
}
//向栈中添加元素
voidpush(MStack*s,MStackEleme)
{
//向栈中添加元素前先判断栈是否还有空间容纳新元素
if(s->top-s->base>=s->stackSize){//栈满,追加元素
s->base=(MStackElem*)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(MStackElem));
if(!
s->base)
exit(OVERFLOW);//存储分配失败
s->top=s->base+s->stackSize;//因为是重新分配了空间,所以base的值其实已经改变,所以top的值也就相应的改变,才能指向新的迷宫栈
s->stackSize+=STACKINCREMENT;
}
*(s->top++)=e;
}
//获得栈顶元素
MStackElemgetTop(MStack*s)
{
if(s->top==s->base){
printf("ingetTop(),emptystack!
exitnow.");
exit(ERROR);
}
else{
return*(s->top-1);
}
}
//删除栈顶元素
voidpop(MStack*s){
//若栈不为空,则删除s的栈顶元素
if(s->top==s->base)
exit(ERROR);
else{
--(s->top);
}
}
MStackrealPath,path;
//判断当前位置是否走过
intunPass(MStackpath,MStackElemcur)
{//这里不能传path的地址,否则在遍历过程中它的top值就真的被改了!
!
intflag=1;
while(path.top!
=path.base)
{
MStackEleme=*(path.top-1);
if(e.x==cur.x&&e.y==cur.y)
{
flag=0;
}
//每循环一次令头指针下移一个位置
(path.top)--;
}
returnflag;
}
//获得东面相邻的位置
MStackElemgetEast(MStackElemcur){
if(cur.y!
=7)
{//当y==7时已到了迷宫右边界,不能再向东(右)行了
cur.y+=1;
cur.val=maze[cur.x][cur.y];
}
returncur;//当y==7时返回的是它本身
}
//获得南面相邻的位置
MStackElemgetSouth(MStackElemcur){
if(cur.x!
=7){//当x==7时已到了迷宫下边界,不能再向南(下)行了
cur.x+=1;
cur.val=maze[cur.x][cur.y];
}
returncur;//当x==7时返回的是它本身
}
//获得西面相邻的位置
MStackElemgetWest(MStackElemcur)
{
if(cur.y!
=0)
{//当y==0时已到了迷宫左边界,不能再向西(左)行了
cur.y-=1;
cur.val=maze[cur.x][cur.y];
}
returncur;//当y==0时返回的是它本身
}
//获得北面相邻的位置
MStackElemgetNorth(MStackElemcur){
if(cur.x!
=0){//当cur.x==0时表示在迷宫的上边界,不能再向北(上)行了
cur.x-=1;
cur.val=maze[cur.x][cur.y];
}
returncur;//当cur.x==0时返回的还是它本身
}
//获得下一个可通行的位置,按东南西北的方向试探
MStackElemgetNext(MStackElemcur){
MStackElemnext;
next.x=next.y=next.val=-1;
if(getEast(cur).val!
=0&&unPass(path,getEast(cur))){
next=getEast(cur);
}
elseif(getSouth(cur).val!
=0&&unPass(path,getSouth(cur))){
next=getSouth(cur);
}
elseif(getWest(cur).val!
=0&&unPass(path,getWest(cur))){
next=getWest(cur);
}
elseif(getNorth(cur).val!
=0&&unPass(path,getNorth(cur))){
next=getNorth(cur);
}
//如果当前位置的四面或为墙或已走过,则返回的next的val值为-1
returnnext;
}
intgetMazePath(){//获得迷宫路径的函数
MStackElemstart,end,cur;
start.x=0;
start.y=0;
start.val=maze[start.x][start.y];
end.x=7;
end.y=7;
end.val=maze[end.x][end.y];
cur=start;//设定当前为位置为"入口位置"
do
{
if(unPass(path,cur))
{//如果当前位置未曾走到过
push(&realPath,cur);
push(&path,cur);
cur=getNext(cur);
if(cur.x==end.x&&cur.y==end.y)
{//到达出口了,则跳出循环,并返回true
//把出口结点放入路径中
push(&realPath,cur);
push(&path,cur);
//直接跳出函数(而不只是跳出这个循环)
returntrue;
}
elseif(cur.val==-1)
{//当前位置的四面或为墙或已走过
//删除真实路径的栈顶元素
pop(&realPath);
cur=getTop(&realPath);//令cur指向栈顶元素
}
}
else
{//如果当前位置已经走过,说明原来测试的方向不对,现在尝试其它方向
cur=getNext(cur);
if(cur.val==-1)
{//仍不通,删除真实路径的栈顶元素
pop(&realPath);
cur=getTop(&realPath);//令cur指向栈顶元素
}
}
}
while(cur.x!
=end.x||cur.y!
=end.y);
}
//打印迷宫路径
voidprintMazePath(MStack*s)
{//为了安全,这里不传MStack的地址,以防在遍历的过程中把它们的top或base的值也修改了
MStackEleme;
while(s->base<(s->top-1))
{
e=*(s->base);//先指向栈底元素,以后依次向上增1
printf("maze[%d][%d]----->",e.x,e.y);
(s->base)++;
}
e=*(s->base);
printf("出口坐标坐标[%d][%d]",e.x,e.y);
}
voidmain()
{
initStack(&
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构课程设计报告 魏子涵100901120 数据结构 课程设计 报告 魏子涵 100901120
![提示](https://static.bdocx.com/images/bang_tan.gif)