数据结构 课程设计 校园最短路径问题.docx
《数据结构 课程设计 校园最短路径问题.docx》由会员分享,可在线阅读,更多相关《数据结构 课程设计 校园最短路径问题.docx(15页珍藏版)》请在冰豆网上搜索。
![数据结构 课程设计 校园最短路径问题.docx](https://file1.bdocx.com/fileroot1/2022-11/28/0432c1fe-7e3e-4fcf-8a77-fe51a1779028/0432c1fe-7e3e-4fcf-8a77-fe51a17790281.gif)
数据结构课程设计校园最短路径问题
一、课程设计题目:
校园最短路径问题
二、课程设计目的:
1.了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法
和技能;
3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;
4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所具备的科学工作方法和作风。
三、课程设计要求:
1.设计的题目要求达到一定的工作量(300行以上代码),并具有一定的深度和
难度。
2.编写出课程设计报告书,内容不少于10页(代码不算)。
四、需求分析:
1、问题描述
图的最短路径问题是指从指定的某一点v开始,求得从该地点到图中其它各地点的最短路径,并且给出求得的最短路径的长度及途径的地点。
除了完成最短路径的求解外,还能对该图进行修改,如顶点以及边的增删、边上权值的修改等。
校园最短路径问题中的数据元素有:
a)顶点数
b)边数
c)边的长度
2、功能需求
要求完成以下功能:
a)输出顶点信息:
将校园内各位置输出。
b)输出边的信息:
将校园内每两个位置(若两个位置之间有直接路径)的距离输出。
c)修改:
修改两个位置(若两个位置之间有直接路径)的距离,并重新输出每两个位置(若两个位置之间有直接路径)的距离。
d)求最短路径:
输出给定两点之间的最短路径的长度及途径的地点或输出任意一点与其它各点的最短路径。
e)删除:
删除任意一条边。
f)插入:
插入任意一条边。
3、实现要点
a)对图的创建采用邻接矩阵的存储结构,而且对图的操作设计成了模板类。
为了便于处理,对于图中的每一个顶点和每一条边都设置了初值。
b)为了便于访问,用户可以先输出所有的地点和距离。
c)用户可以随意修改两点之间好的距离。
d)用户可以增加及删除边。
e)当用户操作错误时,系统会出现出错提示。
五、概要设计:
1.抽象数据类型图的定义如下:
ADTGraph{
数据对象V:
V是具有相同特性数据元素的集合,称为顶点集。
数据关系R:
R={VR}
VR={(v,w)|v,w∈V,(v,w)表示v和w之间存在路径}
基本操作P:
CreatGraph(&G,V,VR)
初始条件:
V是图的顶点集,VR是图中边的集合。
操作结果:
按定义(V,VR)构造图G。
DestroyGraph(&G)
初始条件:
图G已存在。
操作结果:
销毁图。
LocateVex(G,u)
初始条件:
图G存在,u和G中顶点具有相同特征。
操作结果:
若G中存在顶点u,则返回该顶点在图中“位置”;否则返回
其它信息。
GetVex(G,v)
初始条件:
图G存在,v是G中某个顶点。
操作结果:
返回v的信息。
InsertVex(&G,v)
初始条件:
图G存在,v和G中顶点具有相同特征。
操作结果:
在图G中增添新顶点v。
DeleteVex(&G,v)
初始条件:
图G存在,v和G中顶点具有相同特征。
操作结果:
删除G中顶点v及其相关的边。
InsertArc(&G,v,w)
初始条件:
图G存在,v和w是G中两个顶点。
操作结果:
在G中增添弧,若G是无向的,则还增添对称弧。
DeleteArc(&G,v,w)
初始条件:
图G存在,v和w是G中两个顶点。
操作结果:
在G中删除弧,若G是无向的,则还删除对称弧。
}ADTGraph
2.主程序
voidmain()
{
初始化;
while(“命令”!
=“退出”)
{
Switch语句
接受命令(输入选择项序号);
处理命令;
}
}
3.本程序运用函数的调用,只有两个模块,它们的调用关系为:
主程序模块
带权无向图模块
六、详细设计
(详细见下面的源代码)
typedefstruct//图中顶点表示点,存放点名称
voidMenu()//输出菜单
voidPutOutVex(MGraph*G)//输出每个顶点的信息
voidPutOutArc(MGraph*G)//输出每条边的信息
voidDijkstra(MGraph*G)//迪杰斯特拉算法求最短路径
voidDeleteVex(MGraph*G)//删除某个顶点
voidDeleteArc(MGraph*G)//删除某条边
voidInsertArc(MGraph*G)//插入某条边
voidmain()//主函数
七、源程序代码
#include
#include
#include
#include
#include
#include
#defineMAX10000
#defineMAXLEN8
#defineADJTYPEint
typedefstruct//图中顶点表示点,存放点名称
{
charname[30];
intnum;
}VEXTYPE;
typedefstruct
{
VEXTYPEvexs[MAXLEN];//顶点的信息
ADJTYPEarcs[MAXLEN][MAXLEN];//邻接矩阵
intvexnum,arcnum;//顶点数和边数
}MGraph;
MGraphb;
MGraphInitGraph()
{/*建立无向网的邻接矩阵结构*/
inti,j;
MGraphG;
G.vexnum=8;//存放顶点数
G.arcnum=13;//存放边点数
for(i=0;iG.vexs[i].num=i;
strcpy(G.vexs[0].name,"第四教学楼");
strcpy(G.vexs[1].name,"第三教学楼");
strcpy(G.vexs[2].name,"图书馆");
strcpy(G.vexs[3].name,"食堂");
strcpy(G.vexs[4].name,"第一教学楼");
strcpy(G.vexs[5].name,"第二教学楼");
strcpy(G.vexs[6].name,"综合实验楼");
strcpy(G.vexs[7].name,"校医院");
for(i=0;ifor(j=0;jG.arcs[i][j]=MAX;
G.arcs[0][1]=130;
G.arcs[0][2]=80;
G.arcs[0][3]=260;
G.arcs[1][3]=75;
G.arcs[2][4]=50;
G.arcs[3][4]=120;
G.arcs[1][5]=265;
G.arcs[3][5]=85;
G.arcs[3][6]=400;
G.arcs[4][6]=350;
G.arcs[5][6]=120;
G.arcs[4][7]=200;
G.arcs[6][7]=150;
for(i=0;ifor(j=0;jG.arcs[j][i]=G.arcs[i][j];
returnG;
}
voidMenu()//输出菜单
{cout<<"需要输出顶点的信息请按0\n";
cout<<"需要边的信息输出请按1\n";
cout<<"需要修改请按2\n";
cout<<"需要求出最短路径请按3\n";
cout<<"需要删除某个顶点请按4\n";
cout<<"需要删除某条边请按5\n";
cout<<"需要插入某条边请按6\n";
cout<<"需要退出请按7\n";
}
voidPutOutVex(MGraph*G)//输出每个顶点的信息
{
intv;
for(v=0;vvexnum;v++)
cout<vexs[v].num<vexs[v].name<}
voidPutOutArc(MGraph*G)//输出每条边的信息
{
for(inti=0;ivexnum;i++)
for(intj=0;jvexnum;j++)
if(G->arcs[i][j]{cout<<"从"<vexs[i].name<<"到"<vexs[j].name<arcs[i][j]<}
}
voidChange(MGraph*G)//修改
{intv0,v1,length;
cout<<"change\n";
cin>>v0;
cin>>v1;
cout<<"length:
";
cin>>length;
G->arcs[v0][v1]=G->arcs[v1][v0]=length;
}
voidDijkstra(MGraph*G)//迪杰斯特拉算法求最短路径
{
intv,w,i,min,t=0,x,v0,v1;
intfinal[20],D[20],p[20][20];
cout<<"请输入源顶点:
\n";
cin>>v0;
if(v0<0||v0>G->vexnum)
{
cout<<"此点编号不存在!
请重新输入顶点编号:
";
cin>>v0;
}
cout<<"请输入结束顶点:
\n";
cin>>v1;
if(v1<0||v1>G->vexnum)
{
cout<<"此点编号不存在!
请重新输入顶点编号:
";
cin>>v1;
}
for(v=0;vvexnum;v++)
{//初始化final[20],p[20][20],final[v]=1即已经求得v0到v的最短路径,
//p[v][w]=1则是w从v0到v当前求得最短路径上的顶点,D[v]带权长度
final[v]=0;
D[v]=G->arcs[v0][v];
for(w=0;wvexnum;w++)
p[v][w]=0;
if(D[v]{
p[v][v0]=1;p[v][v]=1;
}
}
D[v0]=0;final[v0]=1;
for(i=1;ivexnum;i++)
{
min=MAX;
for(w=0;wvexnum;w++)
if(!
final[w])
if(D[w]final[v]=1;
for(w=0;wvexnum;w++)
if(!
final[w]&&(min+G->arcs[v][w]{
D[w]=min+G->arcs[v][w];
for(x=0;xvexnum;x++)
p[w][x]=p[v][x];
p[w][w]=1;
}
}
cout<<"从"<vexs[v0].name<<"到"<vexs[v1].name<<"的最短路径长度为:
"<cout<<"路径为:
";
for(intj=0;jvexnum;j++)
{
if(p[v1][j]==1)
cout<vexs[j].name<}
}
voidDeleteVex(MGraph*G)//删除某个顶点
{
introw,col;
intv0;
cout<<"请输入要删除的顶点";
cin>>v0;
for(inti=v0;ivexnum;i++)
G->vexs[i]=G->vexs[i+1];
G->vexnum--;
for(row=0;rowvexnum;row++)
{
for(col=v0;colvexnum;col++)
G->arcs[row][col]=G->arcs[row][col+1];
}
for(col=0;colvexnum;col++)
{
for(row=v0;rowvexnum;row++)
G->arcs[col][row]=G->arcs[col][row+1];
}
}
voidDeleteArc(MGraph*G)//删除某条边
{
intv0,v1;
cout<<"请输入两顶点:
\n";
cin>>v0>>v1;
G->arcs[v0][v1]=MAX;
G->arcs[v1][v0]=MAX;
}
voidInsertArc(MGraph*G)//插入某条边
{
intv0,v1,l=0;
cout<<"请输入两顶点:
\n";
cin>>v0>>v1;
cout<<"请输入路径长度:
\n";
cin>>l;
G->arcs[v0][v1]=l;
G->arcs[v1][v0]=l;
}
voidmain()//主函数
{inta;
b=InitGraph();
Menu();
cin>>a;
while(a!
=7)
{
switch(a)
{
case0:
PutOutVex(&b);Menu();break;
case1:
PutOutArc(&b);Menu();break;
case2:
Change(&b);Menu();break;
case3:
Dijkstra(&b);Menu();break;
case4:
DeleteVex(&b);Menu();break;
case5:
DeleteArc(&b);Menu();break;
case6:
InsertArc(&b);Menu();break;
case7:
exit
(1);break;
default:
break;
}
cin>>a;
}
}
八、调试分析
1)本程序在求最短路径的问题上采用迪杰斯特拉算法解决,虽然该算法与弗洛伊德算法相比时间复杂度低,但每求一条最短路径都必须重新搜索一遍,在频繁查询时会导致查询效率低,而弗洛伊德算法只要计算一次,即可求得每一对顶点之间的最短路径,虽然时间复杂度为高,但以后每次查询只要查表即可,会极大地提高查询的效率,而且,弗洛伊德算法还支持带负权的图的最短路径的计算。
由此可见,选用算法时必须综合各方面因素考虑。
2)由于功能函数较多,在编写程序时将函数逐个添加完成的,就是说,每增加一个函数,进行一次编译运行,此函数通过了再写下一个函数。
或许这种方法比较麻烦,但当有错误时只要针对新加函数进行修改即可。
同时,要充分利用软件所提供的调试功能,这也会大大减少编程人员的负担。
九、调试结果
a)开始界面
b)输出顶点信息
c)输出边的信息
d)修改
e)求最短路径
f)删除某一顶点
g)删除某条边
h)插入某条边
i)退出
十、总结及体会
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,将结论用于实践,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中当然遇到了问题,可以说得是困难重重,毕竟这是不可避免的,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
当指导老师提到用动态数组和链接表来解决这一问题时,我却一头雾水,才发现自己的知识面太窄。
由于编程水平有限,其中迪杰斯特拉算法的C++程序是参考网上的资料,还有顶点的插入设计中没有体现。
我想在以后的学习中,要更注重实践这一环节。