提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
随着高校的发展,校园面积不断扩大,校园内跨区域活动频繁,为了给校内师生和游客等带来更大方面,本系统,将通过迪杰斯特拉算法,求出所需最短路径,进一步加强数字化校园建设。
一、内容
- 设计校园平面图。
- 为实现校园导航系统子功能的管理,设计主控菜单;
- 为来访客人提供图中任意地点相关信息的查询;
- 为来访客人提供图中任意两地点之间最短路线的查询、指点地点到其他所有地点最短路线的查询。
二、设计思路
1.详细设计
⑴.进入导航系统,遍历所有景点及查询两景点间的最短路径都是通过迪杰斯特拉求单源最短路算法来实现,将各景点间的权值存入二维数组map[ ]中,通过迪杰斯特拉算法,每次找距离开始点最近的点,在通过这个点去更新别的边权值,同时将更新的点存储,放入栈中输出即为到终点所走路径。
⑵.查询所有景点信息是先将景点信息存储然后输出,景点信息是利用string.h头文件中的strcpy( )函数将各景点名称及信息存入到结构体中。查询那个输出对应下标存储的字符串。
⑶.返回主界面直接调用函数。
流程图:
2.迪杰斯特拉算法思路
先加入一个节点作为初始结点,然后每轮添加一个节点,这样n - 1轮后就可以得到从初始结点到所有结点的最小距离。
这里我们要用到三个辅助数组:S[i]、path[i]、dist[i],他们分别用来记录结点i是否已经加入到最短路径、加入的结点i的前驱结点、初始结点到结点i的距离。
接下来我们初始化三个数组,S[i]数组初始化全为0,加入初始结点0,S[0] = 1;path[i]数组初始化全为0,表示他们的前驱结点都是0结点,而0结点无前驱结点,path[0] = -1;dist[i]数组初始化的值为初始结点0到i结点的距离。
接下来循环n - 1次,每次都找到当前dist[i]数组中最小的值,把i结点添加到最短路径中且标记S[i] = 1,然后从新添加的i结点去查找它的出边,如果有出边,若出边的边长加上到新加入的i结点的距离小于初始结点到出边结点的距离,则更新初始结点到出边结点的最短距离以及到出边结点的前驱结点,这样执行n - 1轮,S[i]数组的值全变成1,这样就得到了我们就得到从初始结点到其他所有结点的最短距离以及路径。
算法分析:
若图有n个结点,首先要进行n - 1次的循环,找出dist[i]数组值最小的结点,然后遍历所有结点去更新path[i]、dist[i]两个数组,因此,时间复杂度是n^2。
完整代码
#include<stdio.h>
#include<stdlib.h> //调用system()函数清屏
#include<string.h> //调用strcpy( )函数
#define inf 99999999
void navigation();
void Menu();
void Map();
int map[110][110],book[110],dis[110];
struct A //定义结构体存储景点信息
{
char name[100];
char introduce[800];
}q[100];
//东软景点平面图
void Map()
{
system("cls"); //清屏
printf(" 东 软 景 点 平 面 图 \n");
printf(" 18.东软小镇 \n");
printf(" ╱╱100m \n");
printf(" 10.A座教学楼 2.东北门 \n");
printf(" || 10m 300m ╱╱50m \n");
printf(" 11.B座教学楼= = = = = = = = = = = = = = = = = = = = = = = 5.行 政 楼 \n");
printf(" || ╱ ╲╲ 100m \n");
printf(" || 30m ╱ 200m ╲╲ \n");
printf(" || ╱ 4.继续教育学院 \n");
printf(" 6.操场 = = = = = = 12.C座教学楼 ╱╱ \n");
printf(" || 30m || 10m 200m ╱╱ 30m \n");
printf(" || 7.图书馆 = = = = = = = = = = = = = = = = = = 1.东南2门 \n");
printf(" ||50m || 30m╱╱ || \n");
printf(" || || 13.D座教学楼 40m \n");
printf(" 14.E座教学楼 ||50m 20m\\ || \n");
printf(" ||10m || \\ || \n");
printf(" || 30m || 3.国际教育学院 \n");
printf(" 15.F座教学楼 = = = = 8.学二食堂 ╱╱ \n");
printf(" || || ╱╱ \n");
printf(" || ||30m ╱╱200m \n");
printf(" ||30m || ╱╱ \n");
printf(" || 20m || 25m ╱╱ \n");
printf(" 16.女生宿舍 = = = = 9.教工宿舍 = = = = = = 17.男生宿舍 \n");
}
void point() //存储景点信息、同时存图,各边信息
{
int i,j;
strcpy(q[1].name,"东南2门");strcpy(q[1].introduce,"学校大门,设有公交站");
strcpy(q[2].name,"东北门");strcpy(q[2].introduce,"此门离华师最近");
strcpy(q[3].name,"国际教育学院");strcpy(q[3].introduce,"学校国际化的窗口,楼高6层");
strcpy(q[4].name,"继续教育学院");strcpy(q[4].introduce,"离公交站最近,出门就可以坐车,楼高5层");
strcpy(q[5].name,"行政楼");strcpy(q[5].introduce,"行政办公大楼,楼高4层");
strcpy(q[6].name,"操场");strcpy(q[6].introduce,"室外标准田径场");
strcpy(q[7].name,"图书馆");strcpy(q[7].introduce,"建筑面积46000平方米,有丰富的藏书");
strcpy(q[8].name,"学二食堂");strcpy(q[8].introduce,"学校东区,学生食堂");
strcpy(q[9].name,"教工宿舍");strcpy(q[9].introduce,"学校青年教职工租住地");
strcpy(q[10].name,"A座教学楼");strcpy(q[10].introduce,"学院最大的系--计算机系在此,楼高4层");
strcpy(q[11].name,"B座教学楼");strcpy(q[11].introduce,"最早的教学楼之一,楼高4层");
strcpy(q[12].name,"C座教学楼");strcpy(q[12].introduce,"非常多的实验室,翻转课堂教室,楼高4层");
strcpy(q[13].name,"D座教学楼");strcpy(q[13].introduce,"商英系上课集中的地方");
strcpy(q[14].name,"E座教学楼");strcpy(q[14].introduce,"商管系上课集中的地方");
strcpy(q[15].name,"F座教学楼");strcpy(q[15].introduce,"计算机系上课集中的地方");
strcpy(q[16].name,"女生宿舍");strcpy(q[16].introduce,"女生宿舍J1、J2");
strcpy(q[17].name,"男生宿舍");strcpy(q[17].introduce,"男生宿舍J4、J5");
strcpy(q[18].name,"东软小镇");strcpy(q[18].introduce,"19届和21届学生的主要住宿区");
for(i=1;i<=18;i++)
for(j=1;j<=18;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
}
//权重
map[1][3]=40;map[1][4]=30;map[1][7]=200;map[1][13]=30;
map[2][5]=50;map[2][18]=100;
map[3][1]=40;map[3][13]=20;map[3][17]=200;
map[4][1]=30;map[4][5]=100;
map[5][2]=50;map[5][4]=100;map[5][11]=300;map[5][12]=200;
map[6][11]=30;map[6][12]=30;map[6][14]=50;
map[7][1]=200;map[7][8]=50;map[7][12]=10;
map[8][7]=50;map[8][9]=30;map[8][15]=30;
map[9][8]=30;map[9][16]=20;map[9][17]=25;
map[10][11]=10;
map[11][5]=300;map[11][6]=30;map[11][10]=10;
map[12][5]=200;map[12][6]=30;map[12][7]=10;
map[13][1]=30;map[13][3]=20;
map[14][6]=50;map[14][15]=10;
map[15][8]=30;map[15][14]=10;map[15][16]=30;
map[16][9]=20;map[16][15]=30;
map[17][3]=200;map[17][9]=25;
map[18][2]=100;
// for(i=1;i<=18;i++)
// for(j=1;j<=18;j++)
// map[j][i]=map[i][j];
}
void list () //景点列表
{
system("cls"); //清屏
printf("\n\n\n");
printf("\t\t\t\t\t * * * * * * * * * * * * * * ** * * * * * * * * * * * * * *\n");
printf("\t\t\t\t\t * * *景点列表* * *\n");
printf("\t\t\t\t\t * ****************************************************** *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <1>东南2门 <2>东北门 <3>国际教育学院 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <4>继续教育学院 <5>行政楼 <6>操场 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <7>图书馆 <8>学二食堂 <9>教工宿舍 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <10>A座教学楼 <11>B座教学楼 <12>C座教学楼 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <13>D座教学楼 <14>E座教学楼 <15>F座教学楼 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * * <16>女生宿舍 <17>男生宿舍 <18>东软小镇 * *\n");
printf("\t\t\t\t\t * * * *\n");
printf("\t\t\t\t\t * ****************************************************** *\n");
printf("\t\t\t\t\t * * * * * * * * * * * * * * ** * * * * * * * * * * * * * *\n");
printf("\n\n\n");
}
//查询方式
int way(int x)
{
int i;
system("cls"); //清屏
printf("\n");
printf("\t\t\t\t\t *请输入查询方式*\n\n");
printf("\t\t\t\t\t 1、输入景点编号查询\n\n");
printf("\t\t\t\t\t 2、输入景点名称查询\n\n");
printf("\t\t\t\t\t 0、返回上一界面\n\n\n\n\n\n\n");
scanf("%d",&i);
return i;
}
//查询景点编号
int number(char s[])
{
int f=0,i;
for(i=1;i<=18;i++)
{
if(strcmp(q[i].name,s)==0)
return i;
}
return -1;
}
void Dijkstra(int v0,int s) //迪杰斯特拉求最短路径,并输出路线
{
int min,i,j,u,v;
int p[110],l[110];
memset(p,-1,sizeof(p));
memset(l,0,sizeof(l));
memset(book,0,sizeof(book));
for(i=1;i<=18;i++)
{
dis[i]=map[v0][i];
if(dis[i]<inf) //v0能直接到达,即上一站点为v0
p[i]=v0;
}
book[v0]=1;
for(i=1;i<18;i++)
{
min=inf;
for(j=1;j<=18;j++) //每次找出距离v0最近点
{
if(book[j]==0&&dis[j]<min)
{
min=dis[j];
u=j;
}
}
book[u]=1; //标记该点
for(v=1;v<=18;v++)
{
if(book[v]==0&&dis[v]>dis[u]+map[u][v]) //通过最近点更新其他边
{
p[v]=u; //存储更新的边,即为路线
dis[v]=dis[u]+map[u][v];
}
}
}
v=s;
i=1;
while(p[v]!=v0) //将路线存入栈中,正序输出
{
l[i++]=p[v];
v=p[v];
}
printf("\n");
u=i-1;
printf("路线为:\n");
printf("%s--->",q[v0].name);
for(i=u;i>=1;i--)
printf("%s--->",q[l[i]].name);
printf("%s\n",q[s].name);
printf("最短路径长度为:%d 米\n",dis[s]);
}
//导航界面
void navigation()
{
int x,m,n,u,v,i,j;
char c[100];
system("cls"); //清屏
printf("\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 ■ ■\n");
printf("\t\t\t\t ■■■■■■■■■■■■■■■■■■■■■■■\n");
printf("\n\n\n");
printf("\t\t\t 1、遍历所有景点;\t\t\t2、查询任意景点信息;\n\n\n");
printf("\t\t\t 3、查询任意两景点间的最短路径; 4、东软景点平面图;\n\n\n");
printf("\t\t\t 5、返回至主界面;\n");
printf("\n\n\n");
while(1)//实现输入错误可重新输入
{
scanf("%d",&x);
if(x==1)
{
v=way(x);
while(1)
{
if(v==1)
{
list();
printf("请输入当前所在景点编号:\n");
scanf("%d",&n);
while(1)
{
if(n>=1&&n<=18)
{
for(i=1;i<=18;i++)
{
if(i!=n)
Dijkstra(n,i);
}
printf("\n\n按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n该景点不存在!请重新输入景点编号:\n");
scanf("%d",&n);
}
}
break;
}
else if(v==2)
{
list();
printf("请输入当前所在景点名称:\n");
scanf("%s",c);
n=number(c);
while(1)
{
if(n>=1&&n<=18)
{
for(i=1;i<=18;i++)
{
if(i!=n)
Dijkstra(n,i);
}
printf("\n\n按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n该景点不存在!请重新输入景点名称:\n");
scanf("%s",c);
n=number(c);
}
}
break;
}
else if(v==0)
{
navigation();
break;
}
else
{
printf("\n\n输入错误请重新输入!\n\n");
scanf("%d",&v);
}
}
break;
}
else if(x==2)
{
v=way(x);
while(1)
{
if(v==1)
{
list();
printf("请输入景点编号:\n");
scanf("%d",&n);
while(1)
{
if(n>=1&&n<=18)
{
printf("\n\n%s\n\n%s\n\n",q[n].name,q[n].introduce);
printf("按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n该景点不存在!请重新输入景点编号:\n");
scanf("%d",&n);
}
}
break;
}
else if(v==2)
{
list();
printf("请输入景点名称:\n");
scanf("%s",c);
n=number(c);
while(1)
{
if(n>=1&&n<=18)
{
printf("\n\n%s\n\n%s\n\n",q[n].name,q[n].introduce);
printf("按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n该景点不存在!请重新输入景点名称:\n");
scanf("%s",c);
n=number(c);
}
}
break;
}
else if(v==0)
{
navigation();
break;
}
else
{
printf("\n\n输入错误请重新输入!\n\n");
scanf("%d",&v);
}
}
break;
}
else if(x==3)
{
v=way(x);
while(1)
{
if(v==1)
{
list();
printf("请输入起点景点编号:\n");
scanf("%d",&n);
printf("\n请输入终点景点编号:\n");
scanf("%d",&m);
while(1)
{
if(n>=1 && n<=18 && m>=1 && m<=18 && n!=m)
{
Dijkstra(n,m);
printf("\n\n按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n输入不合法!请重新输入!\n\n");
printf("请输入起点景点编号:\n");
scanf("%d",&n);
printf("\n请输入终点景点编号:\n");
scanf("%d",&m);
}
}
break;
}
else if(v==2)
{
list();
printf("请输入起点景点名称:\n");
scanf("%s",c);
n=number(c);
printf("\n请输入终点景点名称:\n");
scanf("%s",c);
m=number(c);
while(1)
{
if(n>=1&&n<=18 &&m>=1&&m<=18 &&n!=m)
{
Dijkstra(n,m);
printf("\n\n按回车键返回至导航系统界面\n\n");
getchar();getchar();
navigation();
break;
}
else
{
printf("\n输入不合法!请重新输入!\n\n");
printf("请输入起点景点名称:\n");
scanf("%s",c);
n=number(c);
printf("\n请输入终点景点名称:\n");
scanf("%s",c);
m=number(c);
}
}
break;
}
else if(v==0)
{
navigation();
break;
}
else
{
printf("\n\n输入错误请重新输入!\n\n");
scanf("%d",&v);
}
}
break;
}
else if(x==4)
{
Map();
printf("\n\n\n\n\n");
printf("按回车键返回主界面\n");
getchar();getchar();
Menu();
break;
}
else if(x==5)
{
Menu();
break;
}
else
{
printf("\n\n输入错误!请重新输入!\n");
}
}
}
//菜单
void Menu()
{
system("cls"); //清屏
int m;
printf("\n\n\n\n\n");
printf("\t\t\t\t\t ******************************************************\n");
printf("\t\t\t\t\t *----------------------主界面------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------1、进入导航系统---------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------2、学校简介-------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------3、退出程序-------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------4、制作人---------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t ******************************************************\n");
scanf("%d",&m);
while(1)
{
if(m==1)
{
navigation();
break;
}
else if(m==2)
{
system("cls");
printf("\n\n\n\n\n");
printf("\t\t\t******************************************************************\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 广东东软学院是经教育部批准设立,由东软控股联合亿达集团共同 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 投资举办的全日制普通本科高等院校,学校为广东省首批省级示范性软 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 件学院、广东省首批依法治校示范校、国家技能型紧缺人才培养基地。 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 学院前身南海东软信息技术职业学院成立于2002年,2014年5月经教*\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 育部批准升格为本科高校。 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t******************************************************************\n");
printf("\n\n\n\n\n");
printf("按回车键返回主界面\n");
getchar();getchar();
Menu();
break;
}
else if(m==3)
{
system("cls");
printf("\n\n\n\n\n");
printf("\t\t\t\t\t∴∵∴∵∴∵∴∵∴∵∴∵∴∵∴\n");
printf("\t\t\t\t\t∴∵ ∴∵\n");
printf("\t\t\t\t\t∴∵ 欢 迎 使 用 ∴∵\n");
printf("\t\t\t\t\t∴∵ ∴∵\n");
printf("\t\t\t\t\t∴∵∴∵∴∵∴∵∴∵∴∵∴∵∴\n");
printf("\n\n\n");
break;
}
else if(m==4)
{
system("cls"); //清屏
printf("\n\n\n\n\n");
printf("\t\t\t\t\t ****************************************************\n");
printf("\t\t\t\t\t * 制作人 *\n");
printf("\t\t\t\t\t * *\n");
printf("\t\t\t\t\t * 广东东软学院计算机学院 *\n");
printf("\t\t\t\t\t * *\n");
printf("\t\t\t\t\t * 20级软件工程1班 *\n");
printf("\t\t\t\t\t * *\n");
printf("\t\t\t\t\t * 张兆江 *\n");
printf("\t\t\t\t\t * *\n");
printf("\t\t\t\t\t ****************************************************\n");
printf("\n\n\n\n\n");
printf("按回车键返回主界面\n");
getchar();getchar();
Menu();
break;
}
else
{
printf("\n\n\n\t\t输入错误请重新输入!\n\n\n\n");
scanf("%d",&m);
}
}
}
//欢迎进入
void welcome()
{
printf("\n\n\n\n\n");
printf("\t\t\t\t\t ******************************************************\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *---------------------Welcome!-----------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *-----------------东软校园导航系统-------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *-------------------按回车键继续---------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t *----------------------------------------------------*\n");
printf("\t\t\t\t\t ******************************************************\n");
getchar();
Menu();
}
int main(void)
{
point();
welcome();
return 0;
}