摘 要
本课程设计实例在给出校园各主要建筑的名称信息及有路 线连通的建筑物之间的距离的基础上,利用校园导航系统计算出给定的起点到终点之间的距 离最近的行进路线,采用弗洛伊德算法,函数调用,最后输出路径及距离。
图1幅,参考文献2篇
目 录
1. 绪论
2. 正文
2.1 需求分析
2.2 系统设计
2.2.1 系统结构概图
2.2.2 功能模块描述
2.3 实现过程
2.3.1 核心模块流程图
2.3.2 运行结果
3. 结论(应当准确、完整、明确精练;也可以在结论或讨论中提出建议、设想、尚待解决问题等。
3.1 存在的不足
3.2 心得体会(程序经验、教训,程序调试及如何纠错等方面阐述)
4. 参考文献
参考文献
附 录
1. 绪论
1.1设计目的:加深对《数据结构》课程所学内容的理解,并通过课程设计,培养分析题目,构建框架,编写代码的能力。
1.2设计内容:设计校园导航系统
1.3主要任务:校园导航系统
2. 正文
问题描述:
当我们参观某校园时,就会遇到这样一个问题:从当前所处位置出发去校园另外某个位 置,要走什么样的路线距离最近?本课程设计实例在给出校园各主要建筑的名称信息及有路 线连通的建筑物之间的距离的基础上,利用校园导航系统计算出给定的起点到终点之间的距 离最近的行进路线
设计要求:
(1)从地图文件中读取校园主要建筑信息及建筑间的距离信息
(2)计算出给定的起点到终点之间的距离最近的行进路线
(3)输出该路线(包含路过哪些建筑)及其总距离
(4)若输入错误,则给出提示信息
2.1 需求分析
1.将学校的主要建筑景点画出来进行标号,可达景点连线赋权值,抽象成无向带权图,顶点为景点,边的权值代表了景点间路径的长度。将学校各代表景点信息及名称运用结构体进行存储,各景点之间的权值存入二维数组 dis[Num][Num]中。
2.显示欢迎界面,并通过按回车键进入导航系统
3.通过菜单输入相应的字母进行查找,本设计中设置了三个选项,查看最短路径,查看信息,退出程序,所以要对相对应的函数进行调用
4.用floyd算法求最短路径并输出
2.2 系统设计
2.2.1 系统结构概图
- 各函数调用关系图如下
2.2.2 功能模块描述
1.抽象数据类型定义模块:
该模块定义了导航图中各个节点的基本结构类型,主要采用邻接矩阵的存储结构来反映各节点之间的路径长度(权值大小)
(有向网节点结构体类型)
typedef struct vertex//定义对各个地点信息存储的结构体类型
{
char name[30] ;
int number;
char introduce[100];
};
2.各地点信息存储模块:
liebiao()--输出景点列表
Init()--按相应编号输入各地点信息,并对各景点间的距离赋值
void liebiao()
{
system("cls"); //清屏
printf("\n");
printf("\t\t\t\t* * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * ** *\n");
printf("\t\t\t\t* * *景点列表* * * * * * *\n");
printf("\t\t\t\t* *************************************************************** *\n");
printf("\t\t\t\t* * <1>兰天公寓 <2>师大西门 <3>西苑餐厅 <4>文科实训楼 * *\n");
printf("\t\t\t\t* * <5>教学10号楼 <6>西操场 <7>教学1号楼 <8>行政1号楼 * *\n");
printf("\t\t\t\t* * <9>师大正门 <10>体育馆 <11>教学7号楼 <12>教学6号楼 * *\n");
printf("\t\t\t\t* * <13>教学4号楼 <14>教学3号楼 <15>逸夫图书馆 <16>博物馆 * *\n");
printf("\t\t\t\t* * <17>教学9号楼 <18>东苑餐厅 <19>美术学院 <20>音乐学院 * *\n");
printf("\t\t\t\t* *************************************************************** *\n");
printf("\t\t\t\t* * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * *\n");
printf("\n");
}
void init()
{
int i,j;//对各个地点进行信息输入,运用strcpy函数
ver[1].number =1; //结构体ver[1]中的number成员
strcpy(ver[1].name,"兰天公寓");
strcpy(ver[1].introduce,"学生住宿楼,有沙滩排球场\n");
ver[2].number =2;
strcpy(ver[2].name,"师大西门");
strcpy(ver[2].introduce,"进出学校\n");
ver[3].number =3;
strcpy(ver[3].name,"西苑餐厅");
strcpy(ver[3].introduce,"学生餐饮文化中心,共有3层,早餐,米饭各种饭菜应有尽有\n");
ver[4].number =4;
strcpy(ver[4].name,"文科实训楼");
strcpy(ver[4].introduce,"可以预定自习室,楼前是如意湖可以欣赏美景\n");
ver[5].number =5;
strcpy(ver[5].name,"教学10号楼");
strcpy(ver[5].introduce,"分为A,B,C,D,E五区,A区自习,上课;B区文学院,哲学院;C区商学院,经济学院;D区法学院,社会发展与公共管理学院\n");
ver[6].number =6;
strcpy(ver[6].name,"西操场");
strcpy(ver[6].introduce,"可以跑步,打羽毛球等\n");
ver[7].number =7;
strcpy(ver[7].name,"教学1号楼");
strcpy(ver[7].introduce,"教学楼\n");
ver[8].number =8;
strcpy(ver[8].name,"行政1号楼");
strcpy(ver[8].introduce,"行政,办公楼\n");
ver[9].number =9;
strcpy(ver[9].name,"师大正门");
strcpy(ver[9].introduce,"有BRT站点(西北师大站)\n");
ver[10].number =10;
strcpy(ver[10].name,"体育馆");
strcpy(ver[10].introduce,"有室内篮球,羽毛球等,体育学院\n");
ver[11].number =11;
strcpy(ver[11].name,"教学7号楼");
strcpy(ver[11].introduce,"教学楼\n");
ver[12].number =12;
strcpy(ver[12].name,"教学6号楼");
strcpy(ver[12].introduce,"计算机科学与工程学院\n");
ver[13].number =13;
strcpy(ver[13].name,"教学4号楼");
strcpy(ver[13].introduce,"教育技术学院\n");
ver[14].number =14;
strcpy(ver[14].name,"教学3号楼");
strcpy(ver[14].introduce,"外国语学院\n");
ver[15].number =15;
strcpy(ver[15].name,"逸夫图书馆");
strcpy(ver[15].introduce,"共3层,自习\n");
ver[16].number =16;
strcpy(ver[16].name,"博物馆");
strcpy(ver[16].introduce,"也是校史馆\n");
ver[17].number =17;
strcpy(ver[17].name,"教学9号楼");
strcpy(ver[17].introduce,"数学与统计学院\n");
ver[18].number =18;
strcpy(ver[18].name,"东苑餐厅");
strcpy(ver[18].introduce,"有美术作品展览\n");
ver[19].number =19;
strcpy(ver[19].name,"美术学院");
strcpy(ver[19].introduce,"有美术作品展览\n");
ver[20].number =20;
strcpy(ver[20].name,"音乐学院");
strcpy(ver[20].introduce,"有音乐厅\n");
for(i=1;i<=Num;i++)//对存储距离的矩阵取值进行初始化,定义为最大
{
for(j=1;j<=Num;j++)
{
edge[i][j]=Max;
}
}
for(i=1;i<=Num;i++)//对距离矩阵进行赋值,由于正反均可所以赋相同的值
{
edge[i][i]=0;
}
edge[1][2]=edge[2][1]=164;
edge[2][3]=edge[3][2]=88;
edge[3][4]=edge[4][3]=400;
edge[2][5]=edge[5][2]=226;
edge[4][6]=edge[6][4]=330;
edge[5][6]=edge[6][5]=350;
edge[5][7]=edge[7][5]=340;
edge[4][8]=edge[8][4]=377;
edge[8][9]=edge[9][8]=186;
edge[6][10]=edge[10][6]=530;
edge[8][10]=edge[10][8]=80;
edge[7][11]=edge[11][7]=200;
edge[11][12]=edge[12][11]=134;
edge[12][10]=edge[10][12]=197;
edge[10][15]=edge[15][10]=268;
edge[12][15]=edge[15][12]=89;
edge[12][13]=edge[13][12]=159;
edge[13][14]=edge[14][13]=60;
edge[14][17]=edge[17][14]=390;
edge[15][16]=edge[16][15]=43;
edge[16][17]=edge[17][16]=46;
edge[17][18]=edge[18][17]=37;
edge[18][19]=edge[19][18]=253;
edge[19][20]=edge[20][19]=282;
}
这里面用了strcpy函数,函数声明:char *strcpy(char *dest,const char*src);dest是指用于存储复制内容的目标数组,src是指要复印的字符串。
3.求最短路径模块:
本模块采用弗洛伊德算法求每一对顶点之间的最短路径,并输出最短路径及距离
void chaxunlujing()/*寻找最短路径*/
{
int i=0,j=0;
while(1)
{
printf("请输入要查询的两点的编号:(以空格间隔)");
scanf("%d %d",&i,&j);
if(i<=Num&&i>0&&j<=Num&&j>0)
{
floyd();
shortest(i,j);
return;
}
}
}
void floyd()//弗洛伊德算法
{
int i=1,j=1,k=1 ;//初始化
for(i=1;i<=Num;i++)
{
for(j=1;j<=Num;j++)
{
dis[i][j]=edge[i][j];
path[i][j]=0;
}
}
for(k=1;k<=Num;k++) //以k作为中转点
{
for(i=1;i<=Num;i++) //遍历整个矩阵,i为行号,j为列号
{
for(j=1;j<=Num;j++)
{
if(dis[i][j]>(dis[i][k]+dis[k][j]))
{
dis[i][j]=(dis[i][k]+dis[k][j]); //更新最短路径
path[i][j]=path[j][i]=k; //中转点为k
}
}
}
}
}
void shortestpath(int i,int j)//输出最短路径
{
int k=0,a=i,b=j;
if(dis[i][j]!=Max)
{
printf("从%s到%s的最短路径为:\n",ver[i].name,ver[j].name);
printf("%s",ver[i].name);
while(path[i][j]!=0)
{
k=path[i][j];
while(path[i][k]!=0)
{
k=path[i][k];
}
printf("-到-%s",ver[k].name);
i=k;
}
printf("-到-%s;\n",ver[j].name );
printf("\n最短距离为:%d米。\n",dis[a][b]);
getchar();getchar();
}
else
printf("从%s不能到达%s。",ver[i].name ,ver[j].name );
}
这里面void shortestpath(int i,int j),括号里的是函数shortestpath的2个形式参数,函数调用时会用实际参数去替换i和j。并将数值带入函数体。
Floyd算法时间复杂度为O(n^3)
4.地点信息显示模块
void information()//输出地点介绍函数
{
int i;
while(1)
{
printf("请输入查询地点的编号:\n\t");
scanf("%d",&i);
if(i<=Num&&i>=1)
{
printf("\n名称:%s\n简介:%s\n",ver[i].name,ver[i].introduce);
getchar();getchar();
return;
}
else
{
printf("输入有误!");
}
}
}
5.主函数模块:
主函数中有欢迎界面和主界面中的菜单选项等,主要是显示导航图中的所有导航节点,能够快速方便的对各个地点进行导航。
int main()
{
char i;
huanyinjiemian();
init();
while (1)
{
i=menu();
switch(i) //进行函数调用
{
case 'a':dispath();break;
case 'b':information();break;
case 'e':printf("\n\n\n\t\t\t\t谢谢使用!\n");return(0);
default :printf("输入错误!\n");break;
}
}
}
void huanyinjiemian()
{
printf("\n\n\n\n\n"); //换行
printf("\t\t\t\t*****************************************************\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* Welcome! *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 西北师范大学校园导航系统 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 按回车键继续 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t******************************************************\n");
getchar(); //用来让程序不会立即退出
liebiao(); //说明下一个界面是列表界面,进行函数声明
}
char menu()
{
char i;
printf("输入“a”查询最短路径\n");
printf("输入“b”查询信息\n");
printf("输入“e”以退出程序\n");
scanf("%s",&i);
return i;
}
Return 代表的是函数的返回值,返回值是指函数被调用之后执行函数体中的代码所得的结果,这个结果通过return 语句返回。
2.3 实现过程
2.3.1 核心模块流程图
核心模块即弗洛伊德算法,floyd算法流程图:
2.3.2 运行结果
1.欢迎界面
2.景点列表
3.输入a查询最短路径
4.输入b查询信息,输入e退出程序
标签:ver,name,西北师范大学,printf,校园,introduce,edge,strcpy,导航系统 From: https://www.cnblogs.com/yangwl/p/16989231.html