1、数据结构课程设计最短路径拯救数据结构课程设计报告( 2011 - 2012 年度第 1 学期)最短路径:拯救007专业计算机科学与技术(网络工程)学生姓名赵宝文班级B计算机102学号1010704227指导教师田明完成日期2012年1月14日最短路径:拯救0071 概 述 1.1 课程设计目的图结构是一种较为复杂的数据结构。对图结构最主要、最基本的操作是图的遍历。典型的遍历方法主要是深度遍历与广度遍历,即深度优先搜索和广度优先搜索。图结构也是一种具有广泛应用的数据结构。图的应用问题主要可归结为:求图中顶点间的最短路径、图的关键路径、图的拓扑排序、图的最小生成树等。本课程设计通过“拯救007”案
2、例回顾图的最短路径的基本知识和基本方法。1.2 课程设计内容看过007系列电影的人们一旦很熟悉Janes Bond这个世界上最著名的特工了。在电影“Live and Let Die”中James Bond被异族毒贩子捉住并且关单哦湖中心的一个小岛上,而湖中有很多凶猛的鳄鱼 。这时James Bond做出了最惊心动魄的事情来逃脱他跳到了最近的鳄鱼头上,在鳄鱼还没有反应过来的时候,他又跳到;额另一只鳄鱼的头上最后他终于安全的跳到了湖岸上。假设湖是100*100的正方形,设湖的中心在(0,0),湖的东北角的坐标是(50,50)。湖中心的原型小岛的圆心在(0,0),直径是15。一些凶残的鳄鱼分布在湖中
3、不同的位置。现已知湖中鳄鱼的位置(坐标)和James Bond可以调的最大距离,请你告诉James Bond一条最短的到达湖边的路径。他逃出去的路径长度等于他跳的次数。输入要求: 程序从“input.txt”,文件中读取输入信息,这个文件包含了多组输入数据。每组输入数 据的起始行中包含两个整数n和d,n是鳄鱼的数量而且n100,d是007可以跳的最大距离而且d0。起始行下面的每一行是鳄鱼的坐标(x,y),其中x,y都是整数,而且没有任何两只鳄鱼出现在同一个位置。input.txt文件以一个负数结尾。 输出要求: 程序结果输出到output.txt文件中。对于每组输人数据,如果007可以逃脱,则
4、输出到output.txt文件的内容格式如下:第一行是007必须跳的最小的步数,然后下面按照跳出顺序记录跳出路径上的鳄鱼坐标(x,y),每行一个坐标。如果007不可能跳出去,则将-1写人文件。如果这里有很多个最短的路径,只需输出其中的任意一种。 输入例子: 4 10 /*第一组输人数据*/ 17 0 27 0 37 0 45 0 1 10 /*第二组输入数据*/ 20 30 -1 输出例子: 5 /*对应第一组数据的输出*/ 17 0 27 0 37 0 45 0 -1 /*对应第二组数据的输出*/2 系统需求分析2.1 系统目标告诉James Bond一条最短的到达湖边的路径。2.2 主体功
5、能假设湖是100*100的正方形,设湖的中心在(0,0),湖的东北角的坐标是(50,50)。湖中心的原型小岛的圆心在(0,0),直径是15。一些凶残的鳄鱼分布在湖中不同的位置。现已知湖中鳄鱼的位置(坐标)和James Bond可以调的最大距离,请你告诉James Bond一条最短的到达湖边的路径。他逃出去的路径长度等于他跳的次数。2.3 开发环境VC+6.03 系统需求分析3.1设计分析1.明确题目中的已知条件(1)007被关的小岛在湖的中心;(2)小岛是圆形,圆心(0,0),而且直径是15;(3)没有两只鳄鱼在同一位置;(4)鳄鱼的坐标值都是整数。2.一些判断007是否跳出的细节(1)判断0
6、07是否能够直接从岛上跳到湖岸:由已知条件可得,湖是一个正方形,变长为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,所以如
7、果两点之间的距离小于等于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经过的最短路径掏出鳄鱼潭时经过的最后一个顶点。可以根据Gk的path参数来追踪改点上的一点,由此类推可以得到007
8、逃脱的最短路径。3.2系统功能模块划分本程序包含3个头文件和4个C源程序文件,分别是:Graph.h、Graph.c、Deque.h、Deque.c、error.h、error.c、main.c。程序内容见附录。4 测试4.1 测试方案测试输入:25 108 89 910 1011 1112 12 13 1314 1415 1516 1618 1820 2021 2123 2325 2527 2728 2829 2931 3133 3335 3538 3841 4144 4446 4647 4749 494.2 测试结果正确输出:79 916 1623 2328 2835 3541 41实际输
9、出: 79 916 1623 2328 2835 3541 415 分析与探讨5.1 测试结果分析 程序能够正常运行,输入测试数据,能够得到正确的结果,能对输入的内容进行数据合法性检测并进行相应的异常处理。5.2 探讨与改进最短路径定义:由图的概念克制,在一个图中,若从一个顶点到另一个顶点存在着一条路径,则称该路径长度为该路径上所有经过的变的数目,他也等于该路径上的顶点数减1.有余从一个顶点到另一个顶点可呢该村在这多条路径,每条径上锁经过的边数可能不同,把路径上长度最短的那条路径叫做最短路径,其路径长度叫做最短距离。上述问题之时队无权图而言,若是带权图,则把从一个顶点到另一条路径上所有经过的权
10、值之和定义为该路径的带全路径长度。把带权路径长度最短的那条路径称为该有权的最短路径,起路径长度称为最短距离。6 小结经过这几天的课程设计,让我受益良多,进一步加深了多数据结构这一门课程的理解,让我的学习更进一步。当然能完成这次课程设计也离不开大家的帮助,老师的指导和同学的帮助。刚开始做这个的时候挺不情愿的,毕竟是上课,不过投入性不高,可是渐渐的随着在实验中不断遇到问题,然后努力解决问题,其中带来了许多乐趣,也有很多成就感,让我发现学习其实挺有趣的,有了兴趣,才有动力,人才能前进,在前进的过程之中找到自己的不足,然后改正它,人才能走的更远站的更高。希望以后还有这样的机会能够锻炼自己,和同学们协作
11、,增加团队精神,以及自己独立思考的能力。参考文献1范策,周世平,胡哓琨.算法与数据结构(C语言版)M. 北京:机械工业出版社,20042 严蔚敏.数据结构(C语言版). 北京:清华大学出版社,20043 许卓群,杨冬青,唐世渭,张铭. 数据结构与算法. 北京:高等教育出版社,20044 徐孝凯. 数据结构实用教程(第二版). 北京:清华大学出版社,2006附 录附录为了记录007跳过的路径,可定义如下结构:typedef unsigned int Vertanca;typedef double Distanca;typedef struct GraphNodeRecord int x; int
12、 y; unsigned int Step; Verex Path;GraphNode;Typedef GrahNode *Graph;寻找跳出路径的算法:/*读入一组测试数据返回007跳过的路径Graph,*Bank记录最短到达湖岸的路径。该算法实际上市应用队列图进行广度搜索,以寻找到岸边的最短路径(最少的边数),其中入队列与出队列函数分别是Inject()和Pop()*/Graph read_case(FILE *InFile, int num, Vertex* Bank, Deque D) Graph G = NULL; Distance JamesJump; Vertex V; int
13、 x, y; int i, Times; *Bank = 0; fscanf(InFile, %lf, &JamesJump); if(CheckForEnd(0, 0, JamesJump + ISLAND_DIAMETER/2.0) for(i = 0; i (num 0) /* 007必须经过鳄鱼头上的情况 */ num += 2; G = GraphNew(num); for(i = 2; i num; i+) /* 第三个node开始是鳄鱼 */ fscanf(InFile, %d, &x); fscanf(InFile, %d, &y); Gi.X = x; Gi.Y = y; i
14、f(CheckForStart(x, y, JamesJump) /*判断是否能跳上该点*/ Gi.Path = 1; /*007可以跳到 */ Gi.Step = 1; /* 一步 */ if(CheckForEnd(x, y, JamesJump) /* 判断该点是否能跳出 */ *Bank = i; /* 007可以跳出 */ Times = (num - i - 1) 1; for(i = 0; i Times; i+) /* 不必检验其他鳄鱼 */ fscanf(InFile, %d, &y); DequeClear(D); break; else Inject(i, D); /* 插入该点,并开始下一个检测 */ while(!IsEmpty(D) /*只经过一个鳄鱼无法跳出,必须还要跳到其它鳄鱼的情况 */ V = Pop(D); for(i = 2; i GV.Step + 1) & CheckForConnect(G, V, i, JamesJump) Gi.Path = V; Gi.Step = GV.St