前言
学校数据结构课程要求做的课程设计
一.设计目的
(1).首先,在选择校园导航系统的图的存储结构时,由于当时还没有确定课题题目,最后一段时光临时学习了图的两种存储结构,由于本人认为邻接矩阵存储比较简单,就选择了该存储结构。
(2).其次,该课程设计是本人第一次进行的比较认真的设计,即使比较简单,但也经历了一个星期左右的设计加调试,在不断选择中所得到的成果,即使最后可能在学校所得到的分数不是很高,但我觉得有一定的纪念意义,索性就发布出来,希望能对大家有一定的帮助。
(3).最后,该系统实现了网上我一直找不到的导航方式的一定功能,并从文件中读取数据,结合网上其他人的方法,给出了我自身对于导航方式的理解。
二.设计内容与要求
一.设计要求
为本校设计一个校园导航程序,具体要求如下:
① 校园地图存储于格式自定义的文本文件中,包括地点编号、名称、简介;道路名称、 长度、 种类(车行、骑行、步行)等信息,至少包含 15 个地点、25 条道路。
② 所存储的校园地图需以图形方式输出。
③ 能根据编号(或名称)查询任意地点、道路的相关信息。
④ 能根据指定的出发、目的地点、导航方式(车行、骑行、步行),计算出最短路径。
⑤ 能为用户提供从指定地点出发游览完其他所有地点的路线信息。 涉及算法及知识:图的创建、遍历、最短路径、文本文件读 API。
二.设计内容
首先,构建校园导航图的各个组成结构:
一:顶点结构
typedef struct Vex //景点信息
{
int position; //编号
char name[Max];//名称
char introduction[100];//介绍
}VexInfo[100];
其中,position是指各个顶点的编号,name指的是顶点名称,introduction是指顶点介绍
二:边结构
typedef struct Rd {
char name[Max];
char infor[40];
int length;
int type; // 1-车行道,2-骑行道,3-步行道
int last; //道路一端的序号
int next; //道路另一端的序号
}Road[100];
该边结构中包含一条边的上一个顶点和下一个顶点,边的名字和介绍,边的长度,最后是边的类型
三:邻接矩阵
typedef struct ArcNode
{
int adj;
}AdjMAtrix;
其实,可以省略该结构体,直接在图结构体中定义邻接矩阵,此处本人不改了
四:图结构体
typedef struct maps //景点的图
{
int VexNum; //顶点数
int ArcNum; //边数
VexInfo ves;//顶点表
Road rd;//边表
AdjMAtrix arcs[Max][Max];//邻接矩阵
}Map;
其中,图的成员包含了顶点数和边数,也包含了顶点信息和边的信息,最后包含一个邻接矩阵
---------------------------------------------------------------------------------------------------------------------------------
三.设计过程
文件路径在我的电脑中为D盘下
fopen和fscanf为文件的两个基本操作,注意在读取文件时要将文本文件的格式转换成ANSI,否则读出来的汉字为乱码,此处重点注意!!!!!!
文件读取操作并不难,直接上网现查就ok,基本都是这么个模式
---------------------------------------------------------------------------------------------------------------------------------
一(定位顶点表下标函数)
基本操作,注意,为使序号与下标一一对应,不管是上方的文件读取中的循环,还是往后的循环,都从下标1开始进行,直到等于顶点数或边数结束
int LocateVex(Map& G, int v) {
//i因为是需要记录使用的变量,因此定义在外部
int i;
//遍历图的一维顶点数组,找到顶点v的下标
for (i = 1; i <= G.VexNum; i++) {
if (G.ves[i].position == v) {
//如果已经找到直接退出循环,不需要再次进入循环
break;
}
}
//如果找不到,输出提示语句,返回-1
if (i > G.VexNum) {
printf("No such vertex.\n");
return -1;
}
//寻找成功返回v的下标
return i;
}
二(无向图创建函数)
参数为Map类型的指针G
(1)在该函数中定义边数和顶点数
(2)并定义了两个图外部的表,在使用read_graph()函数后,顶点表和边表中从文件中读取到了数据
(3)之后两个for循环的操作就是用外部的顶点表和边表为图中的顶点表和边表填充数据
(4)再然后,就是初始化邻接矩阵,并使用最后的双重for循环为邻接矩阵赋边值(即权值)
void CreateUDG(Map* G) {
//设置图的顶点数与边数
int i, j, k;
int v1, v2;
G->VexNum = 20;
G->ArcNum = 31;
Rd road[Max];
Vex ves[Max];
read_graph(ves, road);
for (i = 1; i <= G->VexNum; i++) {
G->ves[i].position = ves[i].position;
strcpy(G->ves[i].name, ves[i].name);
strcpy(G->ves[i].introduction, ves[i].introduction);
}
for (int n = 1; n <= G->ArcNum; n++)
{
strcpy(G->rd[n].name, road[n].name);
strcpy(G->rd[n].infor, road[n].infor);
G->rd[n].last = road[n].last;
G->rd[n].next = road[n].next;
G->rd[n].type = road[n].type;
}
//初始化
for (i = 1; i <= G->VexNum; i++)
{
for (j = 1; j <= G->VexNum; j++)