1 课题描述
(一)基本要求
1、 设计你的学校的校园平面图,所含景点10-15个。以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
2、 为来访客人提供图中任意景点相关信息的查询。
3、 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
4、 提供图中任意景点问路查询,即求任意两个景点之间的所有路径。
5、 提供校园图中多个景点的最佳访问路线查询,即求途经这多个景点的最佳路径。
6、 区分汽车线路与步行线路。
7、 设计一实用的查询界面和功能菜单。
(二)、测试数据
由读者根据实际情况设定。
2 问题分析和任务定义
题目要求我们写一个学校的导游图,并且可以查询有关景点的信息,还可以查找任意两景点的最短路径和所有路径。还要求如果要参观多个景点时,也要找出一个最优的路径。
限制条件要求我们区分出汽车路线还是步行路线。
3 逻辑设计
(1)数组
先用二维数组存储学校景点的名字、信息、距离。
(2)主函数
包括命令调用函数,查看学校全景图函数、查看学校景点信息该函数、输入程序、查询景点间距离、查找所有路径
(
4 详细设计
(1)两个二位数组分别存储校园的景点的名字,具体介绍信息。还有一个数组去存景点间的信息。
(2)具体函数
1、void chushi()//存储景点的距离
2、void menu()//菜单
3、void start()//初始页面。
4、void look()//学校的全景图
5、void mulu()//学校景点的目录
6、void ask()//关于景点信息询问函数
7、void floyed1(int s,int e)//弗洛伊德算法,求最短路
8、void shorter()//调最短路的函数
9、void bfs1(int s,int e,int p,int sum)//深搜函数
10、void all()//求两景点间的所有路径
11、void tree(int n,int m)//求多景点之间的最优路径
12、void lots()//调用函数
13、void command()//命令函数
14、int main()//主函数
5 程序编码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<map>
#include<stdlib.h>
using namespace std;
#define inf 1000000000
int tran[20][20],tran1[20][20];
queue<int>q;
int vis[20],path[20],dis[20][20],apth[20][20];
int a[20],b[20],c[20],d[20];
char view[20][100]= {"",
"这里是学校的入口",
"这是学生进行室内比赛和体育活动的场所",
"这是东校的田径操场,同学们都在这里锻炼身体",
"这是学校的第一座教学楼",
"这是学校的第二座教学楼,也是计算机科学与技术学院的系楼",
"这是学校的第三座教学楼",
"这是学校的第四座教学楼",
"这是学校的第五座教学楼",
"这是学校的第六座教学楼",
"8楼一下是学生实验区,以上是领导老师的办公区域",
"这是学校的图书馆,藏书丰富,是同学们阅读自习的好去处",
"这是举办文艺活动的场所"
};//存储学校景点的信息
char name[20][100]= {"",
"东校大门",
"体育馆",
"田径场",
"一教",
"二教",
"三教",
"四教",
"五教",
"六教",
"七教",
"图书馆",
"大活"
};//存储景点的姓名
void chushi()
{
tran[1][2]=tran[2][1]=200;
tran[1][3]=tran[3][1]=100;
tran[2][6]=tran[6][2]=300;
tran[1][4]=tran[4][1]=500;
tran[4][5]=tran[5][4]=200;
tran[4][6]=tran[6][4]=100;
tran[6][8]=tran[8][6]=50;
tran[5][8]=tran[8][5]=100;
tran[8][9]=tran[9][8]=100;
tran[7][9]=tran[9][7]=100;
tran[5][7]=tran[7][5]=200;
tran[5][11]=tran[11][5]=300;
tran[7][12]=tran[12][7]=150;
tran[10][12]=tran[12][10]=200;
tran1[1][4]=tran1[4][1]=500;
tran1[1][3]=tran1[3][1]=100;
tran1[2][6]=tran1[6][2]=300;
tran1[4][6]=tran1[6][4]=100;
tran1[4][5]=tran1[5][4]=200;
tran1[5][8]=tran1[8][5]=100;
tran1[8][9]=tran1[9][8]=100;
tran1[7][9]=tran1[9][7]=100;
tran1[5][11]=tran1[11][5]=300;
tran1[10][12]=tran1[12][10]=200;
tran1[7][12]=tran1[12][7]=150;
tran[11][12]=tran[12][11]=250;
tran1[11][12]=tran1[12][11]=250;
}//存储景点的距离
void menu()//菜单
{
printf("************************************************\n");
printf(" 1:查看学校的全景图 \n");
printf(" 2:查看某景点的信息 \n");
printf(" 3:两个景点之间的最短路径 \n");
printf(" 4:任意两个景点之间的所有路径 \n");
printf(" 5:求途经这多个景点的最佳路径 \n");
printf(" 6:退出导游系统 \n");
printf("************************************************\n");
}
void start()//初始页面
{
int i;
for(i=0; i<10; i++)
printf("\n");
printf(" *********************************************\n");
printf(" ** **\n");
printf(" ** 欢迎参观山东工商学院导游图 **\n");
printf(" ** **\n");
printf(" *********************************************\n");
printf("按任意键继续......");
getchar();
}
void look()//学校的全景图
{
system("cls");
printf("**************************************山东工商学院东校平面图*************************************************************\n");
printf("| |-------| |-------| |-------| |-------| |\n");
printf("| | 六教 |________| 五教 |________| 三教 |_________| 体育馆|____________________ |\n");
printf("| |-------| |-------| |-------| |-------| | |\n");
printf("| / | \\ | |\n");
printf("| / | \\ | |\n");
printf("| / | \\ | |\n");
printf("| |--------| |--------| |--------| |-------------| |\n");
printf("| | 四教 |____________| 二教 |___________| 一教 |__________________________| 东校大门 | |\n");
printf("| |--------| |--------| |--------| |-------------| |\n");
printf("| |-------| | | | |\n");
printf("| | 七教 | | | | |\n");
printf("| |-------| | | |--------| | |\n");
printf("| | |---------| |---------| | 田径场 |____________| |\n");
printf("| |________| 大活 |___________| 图书馆 | |--------| |\n");
printf("| |---------| |---------| |\n");
printf("|************************************************************************************************************************\n");
printf("按任意键继续......");
getchar();
getchar();
return;
}
void mulu()//学校景点的目录
{
printf("*****************山商东校导图**********************\n");
printf(" 1:东校大门 2:体育馆 3:田径场 4:一教 \n");
printf(" 5:二教 6:三教 7:四教 8:五教 \n");
printf(" 9:六教 10:七教 11:图书馆 12:大活 \n");
printf("***************************************************\n");
}
void ask()//关于景点信息询问函数
{
while(1)
{
system("cls");
mulu();
printf("请输入你想要了解的景点的编号(输入0退出):");
int com;
scanf("%d",&com);
if(com==0)
break;
else if(com>12)
printf("无效的命令\n");
else
{
printf("\n%s\n\n",view[com]);
printf("按任意键继续......");
getchar();
getchar();
}
}
}
void floyed1(int s,int e)//弗洛伊德算法,求最短路
{
int i,j,k;
for(k=1; k<=12; k++)
for (i=1; i<=12; i++)
for(j=1; j<=12; j++)
if (tran[i][j]>tran[i][k]+tran[k][j])
{
tran[i][j]=tran[i][k]+tran[k][j];
apth[i][j]=apth[i][k];
}
printf("最短的距离为:%d\n",tran[s][e]);
printf("路径为:");
k=apth[s][e];
printf("%s",name[s]);
while(s!=e)
{
k=apth[s][e];
s=k;
printf("->%s",name[s]);
}
printf("\n");
}
void shorter()//调最短路的函数
{
int i,j;
for(i=0; i<20; i++)
for(j=0; j<20; j++)
{
dis[i][j]=inf;
if(i==j)
{
tran[i][j]=0;
tran1[i][j]=0;
}
else
{
tran[i][j]=inf;
tran1[i][j]=inf;
}
apth[i][j]=j;
}
chushi();
int start,end1;
system("cls");
mulu();
int com;
printf("请输入你要旅行的方式(步行输1,车行输2):");
scanf("%d",&com);
printf("\n");
printf("请输入要查询的起点:");
scanf("%d",&start);
printf("\n");
printf("请输入要查询的终点:");
scanf("%d",&end1);
printf("\n");
if(start<1||start>12||end1<1||end1>12)
{
printf("该景点不存在,请重新输\n");
return ;
}
else
{
if(com==2)
{
floyed1(start,end1);
}
else
{
for(i=0; i<20; i++)
for(j=0; j<20; j++)
{
tran[i][j]=tran1[i][j];
}
floyed1(start,end1);
}
}
printf("按任意键继续.........");
getchar();
getchar();
}
void bfs1(int s,int e,int p,int sum)//深搜函数
{
int i;
if(s==e)
{
printf("这条路径的长度为:%d\n",sum);
printf("路径为:");
for(i=0; i<p; i++)
{
if(i==p-1)
printf("%s\n",name[path[i]]);
else
printf("%s->",name[path[i]]);
}
}
else
{
for(i=1; i<=12; i++)
{
if(vis[i]==0&&tran[s][i])
{
vis[i]=1;
sum+=tran[s][i];
path[p]=i;
bfs1(i,e,p+1,sum);
vis[i]=0;
sum-=tran[s][i];
}
}
}
return ;
}
void all()//求两景点间的所有路径
{
memset(vis,0,sizeof(vis));
memset(path,0,sizeof(path));
memset(tran,0,sizeof(tran));
memset(tran1,0,sizeof(tran1));
chushi();
int start,end1;
system("cls");
mulu();
int com;
printf("请输入你要旅行的方式(步行输1,车行输2):");
scanf("%d",&com);
printf("\n");
printf("请输入要查询的起点:");
scanf("%d",&start);
printf("\n");
printf("请输入要查询的终点:");
scanf("%d",&end1);
printf("\n");
if(start<1||start>12||end1<1||end1>12)
{
printf("该景点不存在,请重新输\n");
return ;
}
else
{
if(com==2)
{
path[0]=start;
vis[start]=1;
bfs1(start,end1,1,0);
}
else if(com==1)
{
int i,j;
for(i=0; i<20; i++)
for(j=0; j<20; j++)
tran[i][j]=tran1[i][j];
path[0]=start;
vis[start]=1;
bfs1(start,end1,1,0);
}
}
printf("按任意键继续.......");
getchar();
getchar();
}
void tree(int n,int m)//求多景点之间的最优路径
{
int i,j,k;
for(k=1; k<=12; k++)
for (i=1; i<=12; i++)
for(j=1; j<=12; j++)
if (tran[i][j]>tran[i][k]+tran[k][j])
{
tran[i][j]=tran[i][k]+tran[k][j];
apth[i][j]=apth[i][k];
}
int x,y,z;
int ans=0;
int sum=0;
d[0]=b[1];
ans++;
while(1)
{
int max1=inf;
for(i=1;i<=n;i++)
{
for(j=2;j<=m;j++)
{
if(tran[b[i]][c[j]]<max1&&c[j]!=0)
{
x=i;
y=j;
max1=tran[b[i]][c[j]];
}
}
}
if(max1==inf)
break;
sum+=max1;
x=b[x];
z=c[y];
n++;
b[n]=c[y];
c[y]=0;
while(x!=z)
{
k=apth[x][z];
x=k;
d[ans++]=x;
}
}
printf("路径的长度为:%d\n",sum);
printf("路径为:");
printf("%s",name[d[0]]);
for(i=1;i<ans;i++)
{
printf("->%s",name[d[i]]);
}
printf("\n");
}
void lots()//调用函数
{
int i,j;
for(i=0; i<20; i++)
for(j=0; j<20; j++)
{
if(i==j)
{
tran[i][j]=0;
tran1[i][j]=0;
}
else
{
tran[i][j]=inf;
tran1[i][j]=inf;
}
apth[i][j]=j;
}
chushi();
int com;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
system("cls");
mulu();
printf("请输入出行方式(步行输1,车行输2):");
scanf("%d",&com);
printf("\n");
for(i=1;;i++)
{
printf("请输入你要参观的第%d个景点(输入0结束):",i);
scanf("%d",&a[i]);
printf("\n");
if(a[i]==0)
break;
}
b[1]=a[1];
for(j=2;j<i;j++)
c[j]=a[j];
if(com==1)
{
for(i=0;i<20;i++)
for(j=0;j<20;j++)
tran[i][j]=tran1[i][j];
tree(1,i-1);
}
else
{
tree(1,i-1);
}
printf("按任意键继续......");
getchar();
getchar();
}
void command()//命令函数
{
while(1)
{
system("cls");
menu();
int com;
printf("请输入命令:");
scanf("%d",&com);
printf("\n");
if(com==1)
look();
else if(com==2)
ask();
else if(com==3)
shorter();
else if(com==4)
all();
if(com==5)
lots();
else if(com==6)
break;
else
printf("无效的命令\n");
}
return ;
}
int main()//主函数
{
start();
chushi();
system("cls");
menu();
command();
return 0;
}
7 结果分析
程序的空间复杂度为O(N2),时间复杂度为O(N3),主要是在求最短路用的弗洛伊德算法中。程序的运行可以判断一些非法的数据,当访问的景点不存在时会有提醒,命令不存在时也会有提醒。
8 总结
这次的程序设计主要是校园导游系统,可以查看校园全景图,可以查看景点的信息,道路也分为人行道和车行道,还可以查找两景点间的最短路径和所有路径,还可以根据想去看的所有景点推荐一个最佳路径。程序中用了最短路算法和最小生成树算法,还有深搜算法。设计的过程当中遇到了很多的问题,最后通过思考和查找资料等方法将其解决。在设计的过程当中学到了很多,也发现解决一个问题需要有耐心、恒心。通过这次程序设计,使我加深了对数据结构的理解,也提高了自己解决问题的能力。