数据结构课程设计最短路径拯救.docx
- 文档编号:5847489
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:19
- 大小:26.02KB
数据结构课程设计最短路径拯救.docx
《数据结构课程设计最短路径拯救.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计最短路径拯救.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构课程设计最短路径拯救
数据结构课程设计报告
(2011--2012年度第1学期)
最短路径:
拯救007
专业
计算机科学与技术(网络工程)
学生姓名
赵宝文
班级
B计算机102
学号
1010704227
指导教师
田明
完成日期
2012年1月14日
最短路径:
拯救007
1概述
1.1课程设计目的
图结构是一种较为复杂的数据结构。
对图结构最主要、最基本的操作是图的遍历。
典型的遍历方法主要是深度遍历与广度遍历,即深度优先搜索和广度优先搜索。
图结构也是一种具有广泛应用的数据结构。
图的应用问题主要可归结为:
求图中顶点间的最短路径、图的关键路径、图的拓扑排序、图的最小生成树等。
本课程设计通过“拯救007”案例回顾图的最短路径的基本知识和基本方法。
1.2课程设计内容
看过007系列电影的人们一旦很熟悉JanesBond这个世界上最著名的特工了。
在电影“LiveandLetDie”中JamesBond被异族毒贩子捉住并且关单哦湖中心的一个小岛上,而湖中有很多凶猛的鳄鱼。
这时JamesBond做出了最惊心动魄的事情来逃脱——他跳到了最近的鳄鱼头上,在鳄鱼还没有反应过来的时候,他又跳到;额另一只鳄鱼的头上……最后他终于安全的跳到了湖岸上。
假设湖是100*100的正方形,设湖的中心在(0,0),湖的东北角的坐标是(50,50)。
湖中心的原型小岛的圆心在(0,0),直径是15。
一些凶残的鳄鱼分布在湖中不同的位置。
现已知湖中鳄鱼的位置(坐标)和JamesBond可以调的最大距离,请你告诉JamesBond一条最短的到达湖边的路径。
他逃出去的路径长度等于他跳的次数。
输入要求:
程序从“input.txt”,文件中读取输入信息,这个文件包含了多组输入数据。
每组输入数据的起始行中包含两个整数n和d,n是鳄鱼的数量而且n≤100,d是007可以跳的最大距离而且d>0。
起始行下面的每一行是鳄鱼的坐标(x,y),其中x,y都是整数,而且没有任何两只鳄鱼出现在同一个位置。
input.txt文件以一个负数结尾。
输出要求:
程序结果输出到output.txt文件中。
对于每组输人数据,如果007可以逃脱,则输出到output.txt文件的内容格式如下:
第一行是007必须跳的最小的步数,然后下面按照跳出顺序记录跳出路径上的鳄鱼坐标(x,y),每行一个坐标。
如果007不可能跳出去,则将-1写人文件。
如果这里有很多个最短的路径,只需输出其中的任意一种。
输入例子:
410/*第一组输人数据*/
170
270
370
450
110/*第二组输入数据*/
2030
-1
输出例子:
5/*对应第一组数据的输出*/
170
270
370
450
-1/*对应第二组数据的输出*/
2系统需求分析
2.1系统目标
告诉JamesBond一条最短的到达湖边的路径。
2.2主体功能
假设湖是100*100的正方形,设湖的中心在(0,0),湖的东北角的坐标是(50,50)。
湖中心的原型小岛的圆心在(0,0),直径是15。
一些凶残的鳄鱼分布在湖中不同的位置。
现已知湖中鳄鱼的位置(坐标)和JamesBond可以调的最大距离,请你告诉JamesBond一条最短的到达湖边的路径。
他逃出去的路径长度等于他跳的次数。
2.3开发环境
VC++6.0
3系统需求分析
3.1设计分析
1.明确题目中的已知条件
(1)007被关的小岛在湖的中心;
(2)小岛是圆形,圆心(0,0),而且直径是15;
(3)没有两只鳄鱼在同一位置;
(4)鳄鱼的坐标值都是整数。
2.一些判断007是否跳出的细节
(1)判断007是否能够直接从岛上跳到湖岸:
由已知条件可得,湖是一个正方形,变长为100,中心是在(0,0),四个顶点分别是(50,50),(50,-50),(-50,-50),(-50,50)。
而湖中小岛的直径是15.所以如果007可以跳大于(50-15/2)=42.5,他就可以直接从小岛跳到湖岸,而不是经过鳄鱼。
(2)判断007是否能够从岛上跳到湖中点A:
已知小岛的半径是7.5,假设点A的坐标是(x,y),007的步长是L,则当点A到中心的(0,0)的距离小于等于007的步长加上小岛的半径7.5的时候就能确定007可以从岛上跳到点A,即
(3)判断007是否能从点A跳到点B:
假设007的步长是L,所以如果两点之间的距离小于等于L,则判断007可以冲A跳到B,即;其他情况是007不能从A点跳到B点。
(4)判断007是否能够从点A跳到湖岸:
当从A点到湖岸的距离小于的ing与007的步长的时候,说明他可以从A点跳到湖岸,或;其他情况时007不能从A点跳到湖岸。
主要数据结构与算法见附录Ⅰ。
在执行完算法read_case后,*Bank值可能有如下3种可能:
(1)0,意味着007无法逃脱出去;
(2)1,意味着007可以直接从岛上跳出去,而不用经过鳄鱼的脑袋;
(3)k,返回的k点是007经过的最短路径掏出鳄鱼潭时经过的最后一个顶点。
可以根据G[k]的path参数来追踪改点上的一点,由此类推可以得到007逃脱的最短路径。
3.2系统功能模块划分
本程序包含3个头文件和4个C源程序文件,分别是:
Graph.h、Graph.c、Deque.h、Deque.c、error.h、error.c、main.c。
程序内容见附录Ⅱ。
4测试
4.1测试方案
测试输入:
2510
88
99
1010
1111
1212
1313
1414
1515
1616
1818
2020
2121
2323
2525
2727
2828
2929
3131
3333
3535
3838
4141
4444
4646
4747
4949
4.2测试结果
正确输出:
7
99
1616
2323
2828
3535
4141
实际输出:
7
99
1616
2323
2828
3535
4141
5分析与探讨
5.1测试结果分析
程序能够正常运行,输入测试数据,能够得到正确的结果,能对输入的内容进行数据合法性检测并进行相应的异常处理。
5.2探讨与改进
最短路径定义:
由图的概念克制,在一个图中,若从一个顶点到另一个顶点存在着一条路径,则称该路径长度为该路径上所有经过的变的数目,他也等于该路径上的顶点数减1.有余从一个顶点到另一个顶点可呢该村在这多条路径,每条径上锁经过的边数可能不同,把路径上长度最短的那条路径叫做最短路径,其路径长度叫做最短距离。
上述问题之时队无权图而言,若是带权图,则把从一个顶点到另一条路径上所有经过的权值之和定义为该路径的带全路径长度。
把带权路径长度最短的那条路径称为该有权的最短路径,起路径长度称为最短距离。
6小结
经过这几天的课程设计,让我受益良多,进一步加深了多数据结构这一门课程的理解,让我的学习更进一步。
当然能完成这次课程设计也离不开大家的帮助,老师的指导和同学的帮助。
刚开始做这个的时候挺不情愿的,毕竟是上课,不过投入性不高,可是渐渐的随着在实验中不断遇到问题,然后努力解决问题,其中带来了许多乐趣,也有很多成就感,让我发现学习其实挺有趣的,有了兴趣,才有动力,人才能前进,在前进的过程之中找到自己的不足,然后改正它,人才能走的更远站的更高。
希望以后还有这样的机会能够锻炼自己,和同学们协作,增加团队精神,以及自己独立思考的能力。
参考文献
[1]范策,周世平,胡哓琨.《算法与数据结构(C语言版)》[M].北京:
机械工业出版社,2004
[2]严蔚敏.《数据结构(C语言版)》.北京:
清华大学出版社,2004
[3]许卓群,杨冬青,唐世渭,张铭.《数据结构与算法》.北京:
高等教育出版社,2004
[4]徐孝凯.《数据结构实用教程(第二版)》.北京:
清华大学出版社,2006
附录
附录Ⅰ
为了记录007跳过的路径,可定义如下结构:
typedefunsignedintVertanca;
typedefdoubleDistanca;
typedefstructGraphNodeRecord{
intx;
inty;
unsignedintStep;
VerexPath;
}GraphNode;
TypedefGrahNode*Graph;
寻找跳出路径的算法:
/*读入一组测试数据返回007跳过的路径Graph,*Bank记录最短到达湖岸的路径。
该算法实际上市应用队列图进行广度搜索,以寻找到岸边的最短路径(最少的边数),其中入队列与出队列函数分别是Inject()和Pop()*/
Graphread_case(FILE*InFile,intnum,Vertex*Bank,DequeD)
{
GraphG=NULL;
DistanceJamesJump;
VertexV;
intx,y;
inti,Times;
*Bank=0;
fscanf(InFile,"%lf",&JamesJump);
if(CheckForEnd(0,0,JamesJump+ISLAND_DIAMETER/2.0))
{
for(i=0;i<(num<<1);i++)/*一步便跳出的情况*/
fscanf(InFile,"%d",&x);
*Bank=1;
}
elseif(num>0)/*007必须经过鳄鱼头上的情况*/
{
num+=2;
G=GraphNew(num);
for(i=2;i { fscanf(InFile,"%d",&x); fscanf(InFile,"%d",&y); G[i].X=x; G[i].Y=y; if(CheckForStart(x,y,JamesJump))/*判断是否能跳上该点*/ { G[i].Path=1;/*007可以跳到*/ G[i].Step=1;/*一步*/ if(CheckForEnd(x,y,JamesJump))/*判断该点是否能跳出*/ { *Bank=i;/*007可以跳出*/ Times=(num-i-1)<<1; for(i=0;i fscanf(InFile,"%d",&y); DequeClear(D); break; } else Inject(i,D);/*插入该点,并开始下一个检测*/ } } while(! IsEmpty(D))/*只经过一个鳄鱼无法跳出,必须还要跳到其它鳄鱼的情况*/ { V=Pop(D); for(i=2;i { if((G[i].Step>G[V].Step+1) &&CheckForConnect(G,V,i,JamesJump)) { G[i].Path=V; G[i].Step=G[V].Step+1; if((G[i].Step &&CheckForEnd(G[i].X,G[i].Y,JamesJump)) *Bank=i; else Inject(i,D); } } } } returnG; } /******写出结果,即最短路径******/ voidwrite_result(FILE*OutFile,VertexBank,GraphG,DequeD) { unsignedintTimes,i; VertexV; switch(Bank){ case0: /*007无法跳出*/ fprintf(OutFile,"%d\n",-1); break; case1: /*007可以直接跳出*/ fprintf(OutFile,"%d\n",1); break; default: Times=G[Bank].Step+1;/*跳的步数*/ while(Bank! =1)/*跟踪路径*/ { Push(Bank,D); Bank=G[Bank].Path; } fprintf(OutFile,"%d\n",Times);/*输出*/ for(i=1;i { V=Pop(D); fprintf(OutFile,"%d",G[V].X); fprintf(OutFile,"%d\n",G[V].Y); } } } intmain(intargc,char*argv[]) { FILE*in,*out; DequeD; intVertexNum; GraphG=NULL; VertexBank=0; in=fopen("input.txt","r"); if(NULL==in) { fprintf(stderr,"Cannotopeninput.txt"); exit(-1); } out=fopen("output.txt","w"); if(NULL==out) { fprintf(stderr,"Cannotopenoutput.txt"); fclose(in); exit(-1); } D=DequeNew(); while((EOF! =fscanf(in,"%d",&VertexNum))&&(0<=VertexNum)) { G=read_case(in,VertexNum,&Bank,D);/*读文件直到结尾*/ write_result(out,Bank,G,D); if(G) GraphDelete(G); } fclose(in); fclose(out); DequeDelete(D); return0; } 附录Ⅱ Graph.h #ifndef_GRAPH_H_ #define_GRAPH_H_ #defineISLAND_DIAMETER15/*小岛的直径*/ #defineLAKE_BOUNDARY_X50/*小岛到湖边的距离,在x轴上*/ #defineLAKE_BOUNDARY_Y50/*小岛到湖边的距离,在y轴上*/ #defineINFINITY10000/*可以跳的步数的最大值*/ typedefunsignedintVertex; typedefdoubleDistance; typedefstructGraphNodeRecord{ intX;/*x轴坐标*/ intY;/*y轴坐标*/ unsignedintStep;/*跳至该点的步数*/ VertexPath;/*记录上一个点*/ }GraphNode; typedefGraphNode*Graph; GraphGraphNew(intNodeNum); voidGraphDelete(GraphG); /*判断007是否能从起始处跳至该点(x,y)*/ intCheckForStart(intx,inty,Distanced); /*判断007是否能从该点跳至河岸*/ intCheckForEnd(intx,inty,Distanced); /*判断007是否能从点i跳至点j*/ intCheckForConnect(Graphg,Vertexi,Vertexj,Distanced); #endif Graph.c #include"Graph.h" #include"error.h" #include /******创建新的Graph******/ GraphGraphNew(intNodeNum) { GraphG; inti; if(NodeNum<=0)returnNULL; G=malloc(NodeNum*sizeof(GraphNode));/*分配空间*/ CHECK(G); for(i=0;i { G[i].X=0; G[i].Y=0; G[i].Step=INFINITY; G[i].Path=0; } returnG; } /******删除一个Graph)******/ voidGraphDelete(GraphG) { if(G)free(G); } /*******判断007是否能从起始处跳至该点(x,y),步长是d******/ intCheckForStart(intx,inty,Distanced) { doublet; t=(ISLAND_DIAMETER+(d*2.0)); return(x*x+y*y)<=t*t/4.0; /*x^2+y^2<=(ISLAND_DIAMETER/2.0+d)^2*/ } /*******判断007是否能从该点跳至河岸,步长是d******/ intCheckForEnd(intx,inty,Distanced) { if(x<0)x=-x;/*取x的绝对值*/ if(y<0)y=-y;/*取y的绝对值*/ return(d>=LAKE_BOUNDARY_X-x)/*由于湖是个正方形,只需检查这两个距离*/ ||(d>=LAKE_BOUNDARY_Y-y); } /*******判断007是否能从点i跳至点j,步长是d******/ intCheckForConnect(Graphg,Vertexi,Vertexj,Distanced) { intx,y; x=g[i].X-g[j].X; y=g[i].Y-g[j].Y; returnx*x+y*y<=d*d; } Deque.h #ifndef_DEQUE_H_ #define_DEQUE_H_ typedefunsignedintElemType;/*在本程序中ElemType指定为int*/ /*链表形式*/ typedefstructNodeRecord{ ElemTypeElement; structNodeRecord*Next;/*指向下一个node*/ }*Node; typedefstructDequeRecord{ NodeFront,Rear;/*分别指向Deque的前后两个点*/ }*Deque; DequeDequeNew(); voidDequeDelete(DequeD); voidDequeClear(DequeD); intIsEmpty(DequeD); voidPush(ElemTypeX,DequeD); ElemTypePop(DequeD); voidInject(ElemTypeX,DequeD); #endif Deque.c #include"Deque.h" #include"error.h" #include /******创建新的Deque******/ DequeDequeNew() { DequeD; D=malloc(sizeof(structDequeRecord)); CHECK(D); D->Front=D->Rear=malloc(sizeof(structNodeRecord));/*空的头*/ CHECK(D->Front); D->Front->Element=0;/*初始化*/ D->Rear->Next=NULL; returnD; } /******删除Deque******/ voidDequeDelete(DequeD) { if(D) { while(D->Front) { D->Rear=D->Front->Next; free(D->Front); D->Front=D->Rear; } free(D); } } /******DequeClear删除所有的节点除了头节点******/ voidDequeClear(DequeD) { if(D) { while(D->Front->Next)/*删除第一个节点*/ { D->Rear=D->Front->Next->Next; free(D->Front->Next); D->Front->Next=D->Rear; } D->Rear=D->Front; } } /******判断Deque是否为空******/ intIsEmpty(DequeD) { returnD->Front==D->Rear; } /******将X元素压占到D中******/ voidPush(ElemTypeX,DequeD) { NodeNewNode; NewNode=malloc(sizeof(structNodeRecord));/*建立新的节点*/ CHECK(NewNode); NewNode->Element=X; NewNode->Next=D->Front->Next; if(D->Front==D->Rear)/*如果D为空*/ D->Rear=NewNode; D->Front->Next=NewNode;/*压栈*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 路径 拯救