题号:第七题题目:校园导航问题1,需求分析:设计你的学校的平面图,至少包括10个以上的景点(场所),每两个景点间可以有不同的路,且路长也可能不同,找出从任意景点到达另一景点的最佳路径(最短路径)。
要求:(1)以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等有关信息。
(2)为来访客人提供图中任意景点相关信息的查询。
(3)为来访客人提供任意景点的问路查询,即查询任意两个景点之间的一条最短路径。
(4)修改景点信息。
实现提示:一般情况下,校园的道路是双向通行的,可设计校园平面图是一个无向网。
顶点和边均含有相关信息。
选做内容:(1)提供图的编辑功能:增、删景点;增、删道路;修改已有信息等。
(2)校园导游图的仿真界面。
2,设计:2.1 设计思想:<1>,数据结构设计:(1)图。
采用邻接矩阵存储,其中图所用到的结构体为:typedef struct{SeqList vertices; //表示图中的顶点int Edge[MaxVertices][MaxVertices]; //表示图中的边int numOfEdge; //表示图中边的数目}AdjMGraph;(2)景点。
用顺序表存储。
所用到的结构体为:typedef struct{char name[20]; //顶点名称int code; //顶点代号char introduction[50]; //顶点信息简介}DataType;(3)景点之间的连接描述,所用到的结构体为:typedef struct{int row;int col;int weight;}RowColWeight;用图来存放所提供的所有景点,然后用线性表来存放每一个景点的信息,其中包括景点的名称,代号,信息简介,以及其它的一些信息。
这样就将对景点的操作,变成对图中各顶点的操作。
<2>,算法设计:关于本课题的算法,很大部分来源于这学期数据结构课程的学习,其中包括:图的创建,线性表的一些操作。
对于具体的问题实现,都有不同的算法,在下面的分析中,我将详细说明2.2 设计表示:<1>, 函数调用关系及函数说明:首先,main()函数调用Creat()函数,用来创建图,然后调用menu()函数来选择用户所要进行的操作。
其中menu()函数就是一个菜单供使用者来选择他所要进行的相关操作,比如信息的查询,最短路径查询之类。
息;以边表示路径,存放路径长度等有关信息。
图的创建设计流程图为:void Creat(AdjMGraph *G, DataType v[], RowColWeight E[], int n,int e)其中,G 为所创建的图结构体对象,v[] 为所有顶点的集合,它是DataType型,这个类型前面已经介绍过;E[] 存放着各顶点之间的连接关系,它是RowColWeight 型,前面也介绍过;n 表示顶点的个数;e 表示边数。
Creat()函数的功能就是实现图的创建,将已知的景点的一些信息,转换成图的 信息,并进行存储。
:为来访客人提供图中任意景点相关信息的查询。
流程图为:menu() void menu() 他就是一个菜单,供用户选择他们所要进行的操作。
Information1()函数原型为:void Information1() 它的功能就是输入查询景点的信息,并调用Information()Information()函数原型为:void Information(AdjMGraph G, char scenery[]) G 依然是所创建的图的结构体对象,后面所有的G 都是表示这个意思;scenery[] 是在Information1() 中输入的景点的名称。
此函数的功能就是根据输入的景点的名称来查询其相关的信息。
对于要求3:为来访客人提供任意景点的问路查询,即查询任意两个景点之间的一条最短路径。
流程图为:void Path1() 它的功能就是输入查询景点的名称,并调用Path()Path ()函数原型为:v oid Path(AdjMGraph G,char sceneryname[], char sceneryname1[])其中sceneryname[], sceneryname1[] 就是在Path1()函数中所输入的景点的名称,这个函数的功能就是通过这两个景点的名称找到它们在线性表中的位置,然后调用Floyd()函数,查找出它们的最短路径,并输出所要的信息。
Floyd()函数原型为:void Floyd (int cost[][ MaxVertices],int n,int weight[][MaxVertices],intpath[][MaxVertices])其中参数cost[][ MaxVertices]即是图中边的邻接存储矩阵,weight[][MaxVertices]用来存放经此算法后的各顶点间的最短路径的值,path[][MaxVertices]就是每两个顶点之间最短路径中到达目的顶点的前一个顶点的位置。
Path()函数中的输出信息就是据此而来。
对于要求4:修改景点信息。
流程图为:void Modify() 它不带任何参数,功能是通过手动输入景点名称,然后找到景点的存储空间,然后在修改相应的信息。
对于选做要求:增加景点。
其工作流程图为:void AddVertic() 他不带任何参数,该函数的功能是在这个函数里面输入景点的信息,然后调用ListInsert()函数,将所要增加的顶点信息插入到线性表中。
ListInsert()函数原型为:void ListInsert(SeqList *L, int i, DataType x) 参数L 表示顶点存储的线性表,i 表示要插入的位置,x 表示要插入的景点的信息。
同时我在插入顶点时也将他与其他顶点之间的距离设置为MaxWeight ,这样做主要是为了方便在Floyd 函数里面求最短路径对于选做要求:删除景点。
其工作流程图为DeleteVertic()函数原型为:void DeleteVertic() 他不带任何参数,该函数的功能就是在函数体里面输入要删除的景点的名称,然后根据名称找到该景点在线性表中的存储位置,然后调用线性表中的 ListDelete ()函数进行相应顶点的删除。
ListDelete ()函数原型为:ListDelete(SeqList *L, int i, DataType *x) 其中参数L 为存放顶点信息的线性表,i 表示要删除顶点在线性表中的存放位置,,x 就是要删除的那一个景点。
它的功能就是从线性表中删除指定的顶点。
对于选做要求:增、删道路,流程图为:void AddRoad()和void DeleteRoad()。
这两个函数都不带参数,它们的功能就是在这两个函数里面输入要删除要增加或者的边连接的两个景点的名称,然后在线性表中找到这两个景点的相对存储空间,最后调用InsertEdge ()或者DeleteEdge ()函数。
InsertEdge ()和DeleteEdge ()两函数原型为:void InsertEdge(AdjMGraph *G, int v1, int v2, int weight)void DeleteEdge(AdjMGraph *G, int v1, int v2) 这两个函数中同名参数所代表的意义是相同的,其中v1, v2是所输入景点在线性表中的相对位置;weight就是增加的边的权值<2>函数接口说明我所设计整个程序就是一些子函数的集合,每个功能都对应一个或者几个子函数,他们之间可以没有任何限制,只要能保证程序正确运行就可以调用,特别是AdjMGraph.h , AdjMGraph.h和SeqList.h头文件之中的函数,他们被很多函数调用过。
这其中都没有任何特殊类型的函数2.3 详细设计:根据题目分析,对于信息查询与修改功能,设计如下:1,输入景点名称2,从线性表头扫描到表尾,if(找到该景点) 输出景点结构体信息else 输出提示信息找不到该顶点实现查找最短路径,设计如下:1,景点名称2,根据输入的信息找到它们所在的线性表中的位置3,调用Floyd算法找出最短路径4,输出信息实现增删景点功能,设计如下:1,增加或者删除景点的名称2,if(输入景点),将景点信息保存在相应的结构体中,并插入到线性表尾;if(删除景点),找到景点在线性表中所在的位置,然后将景点信息从线性表中删除实现增删道路功能,设计如下:1,入增加或删除道路连接的两个景点的名称;2,找到它们的相对位置;3,if(删除道路),将连接它们的边置为MaxWeight;if(增加道路),将输入的边值赋给相应的邻接矩阵表;3,调试分析:<1>,调试过程中遇到的问题与解决方案:1, 关于最短路径的输出问题。
在进行最短路径输出时,我刚开始时只能正序输出,具体的描述为:比如,我要查寻从东区到东湖的最短路径,那么它能正确输出结果,他的形式为:东区——>主楼——>西体育馆——>隧道——>北大门——>东湖。
但是,当我逆向输出时,得到的结果却有点问题,经过分析调试后,找到了错误的所在。
在找最短路径的时候我用的是Floyd算法,在这个算法中有三重循环,形式均为:for(k=0;k<n;k++),它们都是从零开始的,所以在顺序输出时没问题,但是逆序的时候就需要进行一个判断,正序与逆序循环输出是相反的。
2,关于新增加景点后再找最短路径问题。
比如我再新增一个景点,如北区食堂,并输入相关信息,然后插入到线性表尾,当我再找从东区到东湖的最短距离时,输出的最短路径将变为:东区——>食堂——>东湖。
经过分析调试后,其原因也是出在Floyd算法那,在Floyd算法中,有这么一个判断if(weight[i][j]>weight[i][k]+weight[k][j]),由于我在输入新景点信息时并没有建立它与其它景点之间的连接信息,所以在图中,该新景点与其它景点之间的边得连接信息是空的,也就是说在邻接矩阵中,它的边得信息是空的,那么在进行if(weight[i][j]>weight[i][k]+weight[k][j])判断时 weight[新增景点序号][其它景点序号]的值将是一个很大的负数,所以最短路径将会出错。
解决这个问题的方法就是在增加新景点时就将它与其它景点之间的边(距离)设置为MaxWeight,这时如果再用Floyd 函数进行最短路径的求解时就不会再出现问题了。
另外,在做这个题时也还出现过一些其他的小问题,不过都比较容易解决,这里我就不再列出了……<2>,算法的时空复杂度分析对应题目的要求,我总共提供了八个选项操作对于每一个操作的分析如下:1,相关信息的查询。