六.调试情况,设计技巧及体会
1. 对自己的设计进行评价,指出合理和不足之处,提出改进方案;
好的地方:
(1)在文件的存储方面比较满意,先将图的顶点数目和边的数目存入文件,再将顶点信息存入,最后将路线的信息存入文件中。达到了将整个图存入文件的目的,相对于其他存储方法较为简洁且功能完善。
(2)对于查询、增加、删除部分,都先输出已有的景点路线信息,方便用户操作。并且在用户输入错误时会有相应的错误处理。 (3)代码的格式比较整齐,易读。考虑到了很多细节。
不足的地方:
(1) 每次对图进行操作,都要先从文件中读取重建一个图,比较繁琐; (2) 在查找中转路径次数最少的时候调用了查找所有路径的函数,先是
找到所有路径再对次数进行比较,并且若中转次数最少的路径不止一条时,最终只能输出一条路径,有缺陷,算法不够优化;
2. 对设计及调试过程的心得体会。
课程设计刚开始时,思路有点混乱,只知道用文件把图存起来,每次操作时将信息读入图中,具体该怎么实现,还真不知道。看了一下课本,决定用邻接矩阵存储图。图的存储方式决定好后,就开始文件的存储,个人觉得在文件的存储方面想法不错,但是在文件的写入与读取格式的地方出了一点小问题,在调试的
过程中对文件又熟悉了一点。这次课程设计不像以前马马虎虎,漏掉取址符,标点符号等,只会出现逻辑错误,在整个过程中也比较顺利。当不会一些算法的时候,我会查阅资料以及上网百度。把所有的功能实现后就开始细化自己的代码,比如对用户错误输入的错误处理,写小函数如VexExit来让程序更加模块化,以及对界面的改进,只希望自己的代码更加完美。
七.参考文献
(1)数据结构(C语言版) 严蔚敏 吴伟民 编著 清华大学出版社 2002 (2) 数据结构与算法 王曙燕 王春梅 编著 人民邮电出版社 2013
八.附录:源代码(电子版) #include
typedef struct //顶点类型 {
int num; // 景点的编号 char name[20]; //景点的名称 char introduce[100]; // 景点的介绍 }Vextype;
typedef struct //邻接矩阵 {
int arcs[MAXVEX][MAXVEX]; //边集,存放权值 Vextype vex[MAXVEX]; //顶点集 int vexnum; //顶点的数目 int arcnum; //边的数目 }AdjMatrix;
int Locate(AdjMatrix *G,char name[]); //根据景点名称查找景点编号 int VexExit(); //判断景点是否存在 int Creat(AdjMatrix *G); //创建无向图
void Savefile(AdjMatrix *G); //将图保存到文件中
void Readfile(AdjMatrix *G); //从指定文件中读取信息并存入图中 void ShowSchool(AdjMatrix *G); //显示校园全景图 void ShowRoute(AdjMatrix *G); //显示图的所有路线
void ShowVex(AdjMatrix *G); //显示图中所含景点的信息
void Serach(AdjMatrix *G); //查找景点 void AddRoute(AdjMatrix *G); //增加新路线 void DeleteRoute(AdjMatrix *G); //删除旧路线 void AddVex(AdjMatrix *G); //增加新景点 void DeleteVex(AdjMatrix *G); //删除旧景点
void Dijkstra(AdjMatrix *G,int start,int ending,int dist[],int path[][MAXVEX]); //求起点到终点的最短路线
void Prim(AdjMatrix *G,int start); //采用Prim算法求得最短连通路线 void MiniSpanTree(AdjMatrix *G); //查询从某个景点的最短连通路线 void DFS(AdjMatrix *G,int start,int ending,int stack[],int visited[]); //深度遍历查找所有路径
void SimpleRoute(AdjMatrix *G); //查询两个景点间的最优路径 void SearchAllRoute(AdjMatrix *G); //输出两景点之间的所有路径 void menu(); //显示主菜单 void menu1(); //开始菜单界面 void menu2(); //退出菜单界面
int Locate(AdjMatrix *G,char name[]) //根据景点名称查找景点编号 {
int i;
for(i=1;i<=G->vexnum;i++)
if(!strcmp(name,G->vex[i].name)) return i; return -1; }
int VexExit(AdjMatrix *G,int index) //判断景点是否存在 {
if(index>0 && index<=G->vexnum) return 1; else {
printf(\该景点不存在!\\n\ return 0; } }
int Creat(AdjMatrix *G) //创建无向图 {
int i,j,k,weight; char name[20];
printf(\请输入校园图中的景点数目和路线数目:\\n\ scanf(\
for(i=1;i<=G->vexnum;i++) //权值数组初始化 for(j=1;j<=G->vexnum;j++)
G->arcs[i][j]=INFINITY;
printf(\请输入校园图中%d个景点的名称及介绍:\\n\ for(i=1;i<=G->vexnum;i++) {
printf(\请输入第%d个景点:\ G->vex[i].num=i; //flushall();
scanf(\ }
printf(\请输入校园图中的%d条路线:\\n\ for(k=1;k<=G->arcnum;k++) //存入路线 {
printf(\请输入第%d条路线:\\n\ printf(\起点:\ scanf(\ i=Locate(G,name); printf(\终点:\ scanf(\ j=Locate(G,name); printf(\距离:\
scanf(\ G->arcs[i][j]=weight; G->arcs[j][i]=weight; }
return 1; }
void Savefile(AdjMatrix *G) //将图保存到文件中 {
FILE *fp; int i,j;
fp=fopen(\ if(!fp) {
printf(\写文件出错,按任意键退出!\\n\ getch(); exit(1); }
fprintf(fp,\ //先将图的顶点数目和边集数目存入文件,便于控制下面程序的for循环
for(i=1;i<=G->vexnum;i++) //接着存放顶点的信息
fprintf(fp,\
for(i=1;i<=G->vexnum;i++) //最后存放边的信
息即路线信息
for(j=1;j<=i;j++)
if(G->arcs[i][j]!=INFINITY)
fprintf(fp,\
printf(\文件已成功保存,按任意键返回!\\n\ getch(); fclose(fp); }
void Readfile(AdjMatrix *G) //从指定文件中读取信息并存入图中 {
FILE *fp; int i,j;
int start,ending;
char startpoint[20],endpoint[20]; int distance;
fp=fopen(\ if(!fp) {
printf(\读文件出错,按任意键退出!\\n\ getch(); exit(1); }
fscanf(fp,\ //先读取文件中的前两个整型,存入图的顶点数目和边数目中 //对图的权值数组进行初始化 for(i=1;i<=G->vexnum;i++)
for(j=1;j<=G->vexnum;j++) G->arcs[i][j]=INFINITY; //从文件中读取顶点信息并存入图中 for(i=1;i<=G->vexnum;i++) {
G->vex[i].num=i;
fscanf(fp,\ }
//从文件中读取路线并存入图中 for(j=1;j<=G->arcnum;j++) {
fscanf(fp,\ start=Locate(G,startpoint); ending=Locate(G,endpoint); G->arcs[start][ending]=distance; G->arcs[ending][start]=distance; } }