《数据结构课程设计》----校园导航问题
作者:互联网
1.课程设计内容
设计要求:设计你的学校的平面图,至少包括10个以上的场所,每两个场所间可以有不同的路,且路长也可能不同,找出从任意场所到达另一场所的最佳路径(最短路径)。
基本要求:
设计校园平面图,在校园景点选10个左右景点。以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等有关信息。
为来访客人提供图中任意景点相关信息的查询。
为来访客人提供任意景点的问路查询,即查询任意两个景点之间的一条最短路径。
问题分析:
这个校园导航系统,主要是需要构建校园平面图,并将之信息用邻接矩阵存储,然后进行最短路径查找及景点信息查询。
西安工程大学校园平面图如下:
邻接矩阵
(1) 输入形式:输入1个范围1-3的整数,选择功能;若选择功能2,还需输入两个范围1-10的整数,空格隔开
(2) 输出形式:输出10个景点的编号,名称,简介;输出两个点的最短距离及最短路径
(3) 程序功能:功能1将会输出10个景点的编号,名称,简介;功能2将会输出两个点的最短距离及最短路径
(4) 测试数据:
正确数据:
第一组:输入1,输出结果为:
西安工程大学共有以下十处景点:
1.校医院: 校医院由十几位医护组成,负责医保报销,学生生病诊断等服务
2.南环操场: 南环操场是田径场,常在此举行运动会,动员会等仪式
3.计算机科学学院: 计算机科学学院具备多功能机房,是计算机院学生进行实验的地方
4.锅炉房: 锅炉房负责全校师生的热水供应,是学校后勤保障的重要组成部分
5.图书馆: 图书馆内藏书三百余万册,是陕西省十佳图书馆之一
6.东环操场: 东环操场是运动场,具有篮球场,足球场,羽毛球场,网球场等,是学生运动的主要场地
7.C栋教学楼: C栋教学楼主要是全校学生上英语课的地方
8.人文学院: 人文学院主要是人文学院学生上课及实验的地方
9.校门: 校门是西安工程大学的标志型建筑之一,恢弘古典
10.电子信息学院: 电子信息学院主要承担电信学院学生的日常教学工作,具有精密电子实验室
第二组:输入2,再输入1 9,输出为:
校医院->校门的最小路径为:190米
最短路径为: 校医院-> 图书馆-> 人文学院-> 校门
第三组:输入2,再输入4 7,输出为:
锅炉房->C栋教学楼的最小路径为:160米
最短路径为: 锅炉房-> 图书馆-> 计算机科学学院-> C栋教学楼
第四组:输入2,再输入6 2,输出为:
东环操场->南环操场的最小路径为:150米
最短路径为: 东环操场-> 锅炉房-> 校医院-> 南环操场
错误数据:
第一组:输入0,输出:输入错误,请重新输入:
第二组:输入4,输出:输入错误,请重新输入:
第三组:输入2,再输入1 45,输出为:输入错误,请重新输入:
第四组:输入2,再输入3 3,输出为:输入错误,你已经在此地,请重新输入:
2.程序设计
<1>函数定义
(1)GraphCreateGraph() // 初始化图
(2)Graph short_path_floyd(Graph*G,int p[20][20],int d[20][20]) // 弗洛伊德算法,求最短路径
(3)void print() // 界面函数
(4)int main() //主函数
<2>程序流程
(1) 开始
(2) 调用CreateGraph()函数进行初始化
(3) 调用short_path_floyd()函数进行最短路径遍历
(4) 输入一个整数c,选择功能
(5) If(c=1),输出各个景点信息,输出后返回第(4)步
(6) If(c=2),输入两个景点编号,输出两个景点最短路径信息,返回第(4)步
(7) If(c=3),退出程序,结束
<3>程序流程图
3.数据存储结构设计
抽象数据类型定义
typedef struct Vertex
{
int num; //顶点编号
char name[5000]; //顶点名称
char jianjie[15000]; //顶点简介
}Vertex; //结构体定义顶点
typedef struct Graph
{
Vertex vexs[10]; //图中有十个顶点
int arc[20][20]; //图中两点间的弧线权值,也即路程
int vnum,e; // 图中顶点个数和边数
}Graph; //结构体定义图
5.用户使用说明
图(c)程序界面
程序运行界面如上图所示
<1>若要查询景点信息,输入1
<2>若要查询两个景点最短路径,输入2,回车,再输入两个景点编号,空格隔开
<3>若要退出程序,输入3
6.测试结果
正确数据:
第一组:输入1,输出结果为:
西安工程大学共有以下十处景点:
1.校医院: 校医院由十几位医护组成,负责医保报销,学生生病诊断等服务
2.南环操场: 南环操场是田径场,常在此举行运动会,动员会等仪式
3.计算机科学学院: 计算机科学学院具备多功能机房,是计算机院学生进行实验的地方
4.锅炉房: 锅炉房负责全校师生的热水供应,是学校后勤保障的重要组成部分
5.图书馆: 图书馆内藏书三百余万册,是陕西省十佳图书馆之一
6.东环操场: 东环操场是运动场,具有篮球场,足球场,羽毛球场,网球场等,是学生运动的主要场地
7.C栋教学楼: C栋教学楼主要是全校学生上英语课的地方
8.人文学院: 人文学院主要是人文学院学生上课及实验的地方
9.校门: 校门是西安工程大学的标志型建筑之一,恢弘古典
10.电子信息学院: 电子信息学院主要承担电信学院学生的日常教学工作,具有精密电子实验室
第二组:输入2,再输入1 9,输出为:
校医院->校门的最小路径为:190米
最短路径为: 校医院-> 图书馆-> 人文学院-> 校门
第三组:输入2,再输入4 7,输出为:
锅炉房->C栋教学楼的最小路径为:160米
最短路径为: 锅炉房-> 图书馆-> 计算机科学学院-> C栋教学楼
第四组:输入2,再输入6 2,输出为:
东环操场->南环操场的最小路径为:150米
最短路径为: 东环操场-> 锅炉房-> 校医院-> 南环操场
错误数据:
第一组:输入0,输出:输入错误,请重新输入:
第二组:输入4,输出:输入错误,请重新输入:
第三组:输入2,再输入1 45,输出为:输入错误,请重新输入:
第四组:输入2,再输入3 3,输出为:输入错误,你已经在此地,请重新输入:
代码如下:
#include<stdio.h>
#include<stdlib.h>
#define jida 32768 // 定义极大值,代表无穷大
typedef struct Vertex
{
int num; //顶点编号
char name[5000]; //顶点名称
char jianjie[15000]; //顶点简介
}Vertex; //结构体定义顶点
typedef struct Graph
{
Vertex vexs[10]; //图中有十个顶点
int arc[20][20]; //图中两点间的弧线权值,也即路程
int vnum,e; // 图中顶点个数和边数
}Graph; //结构体定义图
Graph*CreateGraph() // 初始化图
{
Graph *G;
int i,j,k;
G=(Graph*)malloc(sizeof(Graph)); //开辟内存
G->e=18; // 图有18条边
G->vnum=10; // 图有十个顶点
for(i=1;i<=G->vnum;i++)
G->vexs[i].num=i; //初始化顶点编号为1-10
for(j=1;j<=10;j++)
for(k=1;k<=10;k++)
{
G->arc[j][k]=jida; // 初始化每两个点间的距离为极大值
}
G->arc[1][2]=G->arc[2][1]=50; //用邻接矩阵存储两点间的权值,依次赋值存储
G->arc[1][5]=G->arc[5][1]=60; // 未在此赋值的弧,其权值为之前初始化的极大值
G->arc[1][4]=G->arc[4][1]=60;
G->arc[2][5]=G->arc[5][2]=75;
G->arc[2][3]=G->arc[3][2]=80;
G->arc[4][6]=G->arc[6][4]=40;
G->arc[4][5]=G->arc[5][4]=40;
G->arc[3][5]=G->arc[5][3]=20;
G->arc[3][7]=G->arc[7][3]=100;
G->arc[5][7]=G->arc[7][5]=400;
G->arc[7][8]=G->arc[8][7]=100;
G->arc[7][9]=G->arc[9][7]=200;
G->arc[8][9]=G->arc[9][8]=30;
G->arc[6][8]=G->arc[8][6]=100;
G->arc[5][8]=G->arc[8][5]=100;
G->arc[5][10]=G->arc[10][5]=400;
G->arc[6][10]=G->arc[10][6]=50;
G->arc[8][10]=G->arc[10][8]=80;
strcpy(G->vexs[1].name,"校医院"); //存储图中每个点的名字,依次赋值存储
strcpy(G->vexs[2].name,"南环操场");
strcpy(G->vexs[3].name,"计算机科学学院");
strcpy(G->vexs[4].name,"锅炉房");
strcpy(G->vexs[5].name,"图书馆");
strcpy(G->vexs[6].name,"东环操场");
strcpy(G->vexs[7].name,"C栋教学楼");
strcpy(G->vexs[8].name,"人文学院");
strcpy(G->vexs[9].name,"校门");
strcpy(G->vexs[10].name,"电子信息学院");
strcpy(G->vexs[1].jianjie,"校医院由十几位医护组成,负责医保报销,学生生病诊断等服务"); //为图中每个景点存储关于它的简介
strcpy(G->vexs[2].jianjie,"南环操场是田径场,常在此举行运动会,动员会等仪式");
strcpy(G->vexs[3].jianjie,"计算机科学学院具备多功能机房,是计算机院学生进行实验的地方");
strcpy(G->vexs[4].jianjie,"锅炉房负责全校师生的热水供应,是学校后勤保障的重要组成部分");
strcpy(G->vexs[5].jianjie,"图书馆内藏书三百余万册,是陕西省十佳图书馆之一");
strcpy(G->vexs[6].jianjie,"东环操场是运动场,具有篮球场,足球场,羽毛球场,网球场等,是学生运动的主要场地");
strcpy(G->vexs[7].jianjie,"C栋教学楼主要是全校学生上英语课的地方");
strcpy(G->vexs[8].jianjie,"人文学院主要是人文学院学生上课及实验的地方");
strcpy(G->vexs[9].jianjie,"校门是西安工程大学的标志型建筑之一,恢弘古典");
strcpy(G->vexs[10].jianjie,"电子信息学院主要承担电信学院学生的日常教学工作,具有精密电子实验室");
return G;
}
Graph* short_path_floyd(Graph*G,int p[20][20],int d[20][20]) // 弗洛伊德算法,求最短路径
{
int v,w,k; // v,w,k分别表示出发点,目的地,新加入的点
for(v=1;v<=G->vnum;v++){
for(w=1;w<=G->vnum;w++)
{
d[v][w]=G->arc[v][w]; // d[20][20]代表两点间最短路径,初始化为两点间权值
p[v][w]=w; // p[20][20]记录最短路径的前一个点
}
}
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() // 界面函数
{
printf("\n\n\n");
printf("\t****************************************\t\n");
printf("\t* 西安工程大学校园导航系统 *\t\n");
printf("\t****************************************\t\n");
printf("\t* *\t\n");
printf("\t* *\t\n");
printf("\t* 1.景点信息查询 *\t\n");
printf("\t* *\t\n");
printf("\t* 2.路线信息查询 *\t\n");
printf("\t* *\t\n");
printf("\t* 3.退出系统 *\t\n");
printf("\t* *\t\n");
printf("\t****************************************\t\n");
printf("\n\n请选择你需要的功能,输入代号:\n");
}
int main()
{
int c,i,f,k,l; // f,k分别为出发点与目的地编号
Graph *T;
int q,w;
int d[20][20]; // d[20][20]代表两点间最短路径
int p[20][20]; // p[20][20]记录最短路径的前一个点
system("color 06"); // 改变输出界面颜色
for(q=1;q<=10;q++)
for(w=1;w<=10;w++)
{
d[q][w]=jida; // 任意两点间最短路径初始化为极大值
}
T=CreateGraph(); // 调用函数初始化图
T=short_path_floyd(T,p,d); //调用函数求最短路径
while(1)
{
print(); // 输出界面栏
scanf("%d",&c); //接受选项
while(c>3||c<1)
{
printf("输入错误,请重新输入:\n");
scanf("%d",&c);
}
if(c==1)
{
printf("\n西安工程大学共有以下十处景点:\n");
for(i=1;i<=10;i++)
{
printf("%d.",T->vexs[i].num); //输出景点编号
printf("%s: ",T->vexs[i].name); //输出景点名字
printf("%s\n\n",T->vexs[i].jianjie); // 输出景点简介
}
}
else if(c==2)
{
printf("请输入当前景点编号和你想要去的景点编号(空格隔开):\n");
scanf("%d %d",&f,&k); // f,k分别接受出发点与目的地编号
while(f<1||f>10||k<1||k>10) //非法输入
{
printf("输入错误,请重新输入:\n");
scanf("%d %d",&f,&k);
}
if(f==k) //非法输入
{
printf("输入错误,你已经在此地,请重新输入:\n");
scanf("%d %d",&f,&k);
}
printf("\n%s->%s的最小路径为:%d米\n",T->vexs[f].name,T->vexs[k].name,d[f][k]);
l=p[f][k]; // l作为中间变量用来接受最短路径中的父亲节点
printf("最短路径为: %s",T->vexs[f].name); // 输出最短路径
while(l!=k)
{
printf("-> %s",T->vexs[l].name);
l=p[l][k]; // 不断更新l节点
}
printf("-> %s\n",T->vexs[k].name);
}
else
break; //退出程序
}
}
标签:vexs,课程设计,20,路径,----,arc,printf,数据结构,输入 来源: https://blog.csdn.net/qq_45909956/article/details/111881026