一. 设计目的
1.设计目标
设计一个校园导游程序,为来访的客人提供各种信息查询服务
2.总体功能
这个校园导航系统,主要是需要构建校园平面图,并将之用邻接矩阵存储,然后进行最短路径查找及景点信息查询。
3.基本要求
(1)展示西安邮电大学的矩阵简化校园平面图
(2)为来访客人提供图中任意景点相关信息查询
(3)为客人提供任意景点的问路查询,即最短路径
二. 各个模块详细的功能描述。
(1)菜单选择界面
程序启动该窗口自动跳出,显示1,2,3,4四个功能,该模块目的是将下面的各个功能进行划分,便于使用者使用方便简洁
(2)校园平面图展示
输出第一个矩阵表,展示各个地点的大致位置
输出第二个矩阵表,说明所有可直接互通地点间的距离
(3)任意地点信息查询
输入您想查询的地点编号:如果该编号不属于1-10中的任意一个,视为输入错误,需要重新输入;当输入正确时,输出您输入的编号,编号代表的地点名称,地点简介
(4)最短路径查询
输入两个编号,分别代表你的当前地点编号和你想去的地点编号:如果这两个编号相等,表明你已经到达目的地,输入错误,需要重新输入;如果两个编号中至少有一个不属于1-10中的任意一个,代表该位置不存在,视为非法输入;当输入正确合理时,先输出两个地点间最短路径的总距离长度,然后输出从第一个编号到第二个编号的最短路径方案。
(5)退出程序
输出“----- 感谢您的使用!-----”,并且退出程序。
//第一个文件,文件名随意
#include"fuction.c"
void view();
void list();
void distance();
Graph*CreateGraph();
void select(int a);
Graph* short_path(Graph* G,int p[20][20],int d[20][20]);
void print_path(int f,int k);
//主函数
int main()
{
int number;
while(1)
{
view();
scanf("%d",&number);
switch(number)
{
case 1:
list();
distance();
system("pause");
system("cls");
break;
case 2:
int aaa;
printf("请输入您想了解的地点编号:> ");
scanf("%d",&aaa);
select(aaa);
break;
case 3:
int f,k;//当前位置和目的位置
printf("请输入您的当前编号和想去的地点编号(空格隔开):> ");
scanf("%d %d",&f,&k);
print_path(f,k);
break;
case 4:
printf("\n\t ------- 感谢您的使用!-------\n");
return 0;
default:
printf("输入错误!");
break;
}
}
return 0;
}
//第二个文件,文件名:function.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 32765//极大值代表无穷大
typedef struct Node
{
int id;//编号
char name[500];//名称
char info[15000];//基本信息
}Node;
typedef struct Graph
{
Node vexs[11];//图中有十个顶点
int arc[20][20];//图中两点间的弧线权值,即路程
int vnum,e;//图中顶点个数和边数
}Graph;//结构体定义图
//菜单界面
void view()
{
printf("\n\t\t*************************\n");
printf("\t\t* 1.校园平面图展示 *\n");
printf("\t\t* 2.查询景点 *\n");
printf("\t\t* 3.路径查询 *\n");
printf("\t\t* 4.退出 *\n");
printf("\t\t*************************\n");
printf("\n请输入您的选择:> ");
}
//以矩阵方式大概描述校园平面图
void list()
{
printf("\t 将校园平面图相对位置以矩阵的方式展示\n");
printf("\t\t __________________\n");
printf("\t\t |1 . . . . 4 . . |\n");
printf("\t\t |. . 2 . . . 9 . |\n");
printf("\t\t |. 3 . . . . . . |\n");
printf("\t\t |. . . . . 5 . . |\n");
printf("\t\t |. . . 8 . . . . |\n");
printf("\t\t |. . 6 . . 7 . . |\n");
printf("\t\t |. . . . . . . 10|\n");
printf("\t\t  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\n");
printf("注:1--安美公寓 2--菜鸟驿站 3--旭日食堂 4--图书馆 5--A教学楼\n");
printf(" 6--研究生院 7--B教学楼 8--中心花园 9--逸夫楼 10--操场\n");
}
void distance()
{
printf("地点间距如下:\n");
printf("\t | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10\n");
printf("\t-------------------------------------------\n");
printf("\t 1 | ∞ |450|450|900| ∞ | ∞ | ∞ | ∞ | ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 2 |450| ∞ |280|640|720| ∞ | ∞ | ∞ | ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 3 |450|280| ∞ | ∞ | ∞ |640| ∞ |560| ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 4 |900|640| ∞ | ∞ |600| ∞ | ∞ | ∞ |280| ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 5 | ∞ |720| ∞ |600| ∞ | ∞ |400|450|460|720\n");
printf("\t-------------------------------------------\n");
printf("\t 6 | ∞ | ∞ |640| ∞ | ∞ | ∞ | ∞ |280| ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 7 | ∞ | ∞ | ∞ | ∞ |400| ∞ | ∞ |450| ∞ |450\n");
printf("\t-------------------------------------------\n");
printf("\t 8 | ∞ | ∞ |560| ∞ |450|280|450| ∞ | ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 9 | ∞ | ∞ | ∞ |280|460| ∞ | ∞ | ∞ | ∞ | ∞ \n");
printf("\t-------------------------------------------\n");
printf("\t 10| ∞ | ∞ | ∞ | ∞ |720| ∞ |450| ∞ | ∞ | ∞ \n\n");
}
//初始化图
Graph*CreateGraph()
{
Graph *G;
int i,j,k;
G=(Graph*)malloc(sizeof(Graph));
G->e=17;//图有17条边
G->vnum=10;//图有10个顶点
for(i=1;i<=G->vnum;i++)
{
G->vexs[i].id=i;//初始化顶点编号为1~10
}
for(j=1;j<=10;j++)
{
for(k=1;k<=10;k++)
{
G->arc[j][k]=MAX;//初始化每两点之间的距离为极大值
}
}
G->arc[1][2]=G->arc[2][1]=450;//用领接矩阵存储两点之间的权值,依次赋值存储
G->arc[1][3]=G->arc[3][1]=450;//未在此赋值的权值为之前存储的极大值
G->arc[1][4]=G->arc[4][1]=900;
G->arc[2][3]=G->arc[3][2]=280;
G->arc[2][4]=G->arc[4][2]=640;
G->arc[2][5]=G->arc[5][2]=720;
G->arc[3][8]=G->arc[8][3]=560;
G->arc[3][6]=G->arc[6][3]=640;
G->arc[4][9]=G->arc[9][4]=280;
G->arc[4][5]=G->arc[5][4]=600;
G->arc[5][9]=G->arc[9][5]=460;
G->arc[5][8]=G->arc[8][5]=450;
G->arc[5][7]=G->arc[7][5]=400;
G->arc[5][10]=G->arc[10][5]=720;
G->arc[6][8]=G->arc[8][6]=280;
G->arc[7][8]=G->arc[8][7]=450;
G->arc[7][10]=G->arc[10][7]=450;
strcpy(G->vexs[1].name,"安美公寓");
strcpy(G->vexs[1].info,"同学们休息的地方,公寓明亮整洁,在这里同学们养精蓄锐");
strcpy(G->vexs[2].name,"菜鸟驿站");
strcpy(G->vexs[2].info,"专门用于取快递的地方,集中放置同学们的快递");
strcpy(G->vexs[3].name,"旭日食堂");
strcpy(G->vexs[3].info,"食堂干净卫生,菜品美味多样,安全健康,让同学们吃饱喝足");
strcpy(G->vexs[4].name,"图书馆");
strcpy(G->vexs[4].info,"在这里同学们可以静下心来好好读书");
strcpy(G->vexs[5].name,"A教学楼");
strcpy(G->vexs[5].info,"同学们上理论课的地方");
strcpy(G->vexs[6].name,"研究生院");
strcpy(G->vexs[6].info,"专门为我校研究生学习开设的地方");
strcpy(G->vexs[7].name,"B教学楼");
strcpy(G->vexs[7].info,"为学生提供实验,实训,学习的场地");
strcpy(G->vexs[8].name,"中心花园");
strcpy(G->vexs[8].info,"这里绿树成荫,花团锦簇");
strcpy(G->vexs[9].name,"逸夫楼");
strcpy(G->vexs[9].info,"通往知识的殿堂");
strcpy(G->vexs[10].name,"操场");
strcpy(G->vexs[10].info,"在这里同学们可以尽情挥洒汗水,运动拼搏");
return G;
}
void select(int aaa)//查找编号对应地点信息
{
Graph *T;
T=CreateGraph();//调用函数初始化图
while(aaa>10||aaa<1)
{
printf("该编号位置不存在,请重新输入:> ");
scanf("%d",&aaa);
}
printf("\n编号:%d ",T->vexs[aaa].id);
printf("名称:%s\t",T->vexs[aaa].name);
printf("\n简介:%s\n\n",T->vexs[aaa].info);
system("pause");
system("cls");
}
//弗洛伊德算法求最短路径
Graph* short_path(Graph* G,int p[20][20],int d[20][20])
{
int v,w,k;//分别代表出发地,目的地 ,新加入的点
for(v=1;v<=G->vnum;v++)
{
for(w=1;w<=G->vnum;w++)
{
d[v][w]=G->arc[v][w];//代表两点之间的最短路径,初始化为两点之间的权值
p[v][w]=w;//记录最短路径的前一个点
}
}
for(k=1;k<=10;k++)//利用三级循环,找出每两个点的最短路径
{
for(v=1;v<=10;v++)
{
for(w=1;w<=10;w++)
{
if(d[v][w]>(d[v][k]+d[k][w]))
{
d[v][w]=d[v][k]+d[k][w];
p[v][w]=p[v][k];
//如果新加入的点组成的路径小于最短路径,则更新最小路径,并将新加入到点加到最短路径中
}
}
}
}
return G;//返回图的类型
}
void print_path(int f,int k)
{
Graph *T;
T=CreateGraph();//调用函数初始化图
int p[20][20];//记录最短路径的前一个点
int d[20][20];//代表两点间最短路径
T=short_path(T,p,d);// 调用函数求最短路径
while(f>10||f<1||k<1||k>10||f==k)
{
if(f<1||f>10||k<1||k>10)
{
printf("非法输入,请重新输入:> ");
scanf("%d %d",&f,&k);
}
if(f==k)
{
printf("您已在该地点,请重新输入:> ");
scanf("%d %d",&f,&k);
}
}
printf("\n%s->%s的最短路径是:%d 米\n",T->vexs[f].name,T->vexs[k].name,d[f][k]);
int l;
l=p[f][k];//l作为中间变量用来接收最短路径中的父亲结点
printf("最短路径为:%s",T->vexs[f].name);//输出最短路径
while(l!=k)
{
printf("-> %s",T->vexs[l].name);
l=p[l][k];//不断更新节点
}
printf("-> %s\n\n",T->vexs[k].name);
system("pause");
system("cls");
}