数据结构校园导游实验报告.docx
《数据结构校园导游实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构校园导游实验报告.docx(38页珍藏版)》请在冰豆网上搜索。
![数据结构校园导游实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/2/2e45c5d4-04ca-45d5-8944-2c6a38e5c66c/2e45c5d4-04ca-45d5-8944-2c6a38e5c66c1.gif)
数据结构校园导游实验报告
数据结构上机实验报告
厦门大学信息科学与技术学院计算机系
姓名:
彭钰杰年级:
2012指导老师:
陈锦绣
实验题目:
校园导游
问题描述:
设计一个校园导游程序,为来访的客人提供各种信息查询服务。
数据结构设计:
因地点与地点之间道路为双向的,所以可看成是一个无向图,本程序采用邻接多重表结构储存,在个别子函数中转化为多维数组以便运算。
实验测试:
构造如下的图:
程序测试图:
主界面
景点道路修改和扩建(模拟地图也会随之更新)
道路导航系统1.最短路径查询
道路导航系统2两点间所有路径
道路导航系统3多地点的最佳路径
求关节点
景点清单
模拟地图
增添景点并为其添加道路数据后模拟地图随之更新
程序中并未加入自动检测输入是否错误的系统,模拟地图系统也会出现边界溢出的情况。
程序代码:
##include
#include
#include
#include
#include
char*heng="━",*shu="┃",*zuos="┏",*zuox="┗",*yous="┓",*youx="┛";
structadjinfo//路信息
{
intlen;//道路长度8
intcategory;//道路类别1:
车道2:
人行道3:
观景路径
intdir;//方向1表示i在j的西边,2表示i在j的北边,3表示i在j的西北边,4表示i在j的西南边.负数则表示相反。
};
structadj//边结构体
{
intmark;
intivex;
intjvex;
adj*ilink,*jlink;
adjinfoinfo;
};
typedefstruct//地点结构体
{
charname[50];
charintro[50];
adj*firstedge;
}site;
typedefstruct
{
sitespot[50];
intspotnum,adjnum;
}graph;
voidinit(graph&t)//初始化图
{
t.adjnum=0;
t.spotnum=0;
}
voidaddsite(char*Name,char*Intro,graph&t)//添加地点
{
strcpy(t.spot[t.spotnum].intro,Intro);
strcpy(t.spot[t.spotnum].name,Name);
t.spot[t.spotnum].firstedge=NULL;
t.spotnum++;
}
voidaddadj(inti,intj,intlength,intcate,intdi,graph&t)//添加道路
{
adj*p1,*p2;
intmark;
p1=(adj*)malloc(sizeof(adj));
p1->ilink=NULL;p1->jlink=NULL;p1->ivex=i;p1->jvex=j;p1->mark=0;
p1->info.category=cate;p1->info.dir=di;p1->info.len=length;
p2=t.spot[i].firstedge;
if(p2==NULL)
t.spot[i].firstedge=p1;
else
{
mark=0;
while(mark==0)
{
if(p2->ivex==i&&p2->ilink==NULL)mark=1;
elseif(p2->jvex==i&&p2->jlink==NULL)mark=2;
elseif(p2->ivex==i)p2=p2->ilink;
elseif(p2->jvex==i)p2=p2->jlink;
}
if(mark==1)
p2->ilink=p1;
else
p2->jlink=p1;
}
p2=t.spot[j].firstedge;
if(p2==NULL)
t.spot[j].firstedge=p1;
else
{
mark=0;
while(mark==0)
{
if(p2->ivex==j&&p2->ilink==NULL)mark=1;
elseif(p2->jvex==j&&p2->jlink==NULL)mark=2;
elseif(p2->ivex==j)p2=p2->ilink;
elseif(p2->jvex==j)p2=p2->jlink;
}
if(mark==1)
p2->ilink=p1;
else
p2->jlink=p1;
}
}
voidDeladj(inti,intj,graph&t)//删除道路
{
intmark;
adj*p1,*p2;
p1=t.spot[i].firstedge;
p2=p1;
mark=0;
while(mark==0)
{
if(p1->ivex==i&&p1->jvex==j&&p2->ivex==i)mark=1;
elseif(p1->ivex==i&&p1->jvex==j&&p2->jvex==i)mark=2;
elseif(p1->jvex==i&&p1->ivex==j&&p2->ivex==i)mark=3;
elseif(p1->jvex==i&&p1->ivex==j&&p2->jvex==i)mark=4;
elseif(p1->ivex==i){p2=p1;p1=p1->ilink;}
elseif(p1->jvex==i){p2=p1;p1=p1->jlink;}
elsemark=5;
}
if(mark==1)
{
if(p1==t.spot[i].firstedge)
{t.spot[i].firstedge=p1->ilink;free(p1);}
else
{
p2->ilink=p1->ilink;
free(p1);
}
}
elseif(mark==2)
{
p2->jlink=p1->ilink;
free(p1);
}
elseif(mark==3)
{
p2->ilink=p1->jlink;
free(p1);
}
elseif(mark==4)
{
if(p1==t.spot[i].firstedge)
{t.spot[i].firstedge=p1->jlink;free(p1);}
else
{
p2->jlink=p1->jlink;
free(p1);
}
}
elseif(mark==5)
printf("找不到该道路\n");
p1=t.spot[j].firstedge;
p2=p1;
mark=0;
while(mark==0)
{
if(p1->ivex==j&&p1->jvex==i&&p2->ivex==j)mark=1;
elseif(p1->ivex==j&&p1->jvex==i&&p2->jvex==j)mark=2;
elseif(p1->jvex==j&&p1->ivex==i&&p2->ivex==j)mark=3;
elseif(p1->jvex==j&&p1->ivex==i&&p2->jvex==j)mark=4;
elseif(p1->ivex==j){p2=p1;p1=p1->ilink;}
elseif(p1->jvex==j){p2=p1;p1=p1->jlink;}
elsemark=5;
}
if(mark==1)
{
if(p1==t.spot[j].firstedge)
{t.spot[j].firstedge=p1->ilink;free(p1);}
else
{
p2->ilink=p1->ilink;
free(p1);
}
}
elseif(mark==2)
{
p2->jlink=p1->ilink;
free(p1);
}
elseif(mark==3)
{
p2->ilink=p1->jlink;
free(p1);
}
elseif(mark==4)
{
if(p1==t.spot[j].firstedge)
{t.spot[j].firstedge=p1->jlink;free(p1);}
else
{
p2->jlink=p1->jlink;
free(p1);
}
}
elseif(mark==5)
printf("找不到该道路\n");
}
voidDelsite(intn,graph&t)//删除地点
{
inti;
while(t.spot[n].firstedge)
{
Deladj(t.spot[n].firstedge->ivex,t.spot[n].firstedge->jvex,t);
}
if(n+1{
for(i=n+1;i{
t.spot[i-1]=t.spot[i];
}
}
t.spotnum--;
}
voidprintfsite(graph&t)//打印景点清单
{
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("┃**┃景点名称┃简介┃\n");
inti;
for(i=0;i{
printf("┃%-2d┃%-20s┃%-38s┃\n",i,t.spot[i].name,t.spot[i].intro);
}
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}
voidgetlmat(graph&t,intcat,intlm[50][50][2])//得到景点路径的矩阵lm[i][j][0]存放路径长度lm[i][j][1]存放方向信息
{
adj*p;
inti,j;
for(i=0;ifor(j=0;j{lm[i][j][1]=0;if(i==j)lm[i][j][0]=0;elselm[i][j][0]=999;}
for(i=0;i{
p=t.spot[i].firstedge;
while(p)
{
if(p->info.category==cat||cat==0)
{
lm[p->ivex][p->jvex][0]=p->info.len;
lm[p->ivex][p->jvex][1]=p->info.dir;
lm[p->jvex][p->ivex][0]=p->info.len;
lm[p->jvex][p->ivex][1]=-p->info.dir;
}
if(p->ivex==i)p=p->ilink;
elsep=p->jlink;
}
}
}
voidgetshortlmat(intmat[50][50][2],graph&t,intpb[50][50][50])//由FLOYD算法得到最短路径矩阵并用pb数组记录中转节点pb[i][j][]表示i->j依次通过的节点。
{
inti,j,k,m,te,g=0,time,m1;
for(i=0;ifor(j=0;jfor(k=0;kpb[i][j][k]=-1;
for(time=0;timefor(i=0;i{
for(j=0;j{
for(k=0;k{
if(mat[i][k][0]+mat[k][j][0]{
mat[i][j][0]=mat[i][k][0]+mat[k][j][0];
te=k;
g=1;
}
if(g==1)
{
m=0;
while(pb[i][te][m]!
=-1)
{
pb[i][j][m]=pb[i][te][m];
m++;
}
pb[i][j][m]=te;m++;
m1=0;
while(pb[te][j][m1]!
=-1)
{
pb[i][j][m+m1]=pb[te][j][m1];
m1++;
}
pb[i][j][m+m1]=-1;
g=0;
}
}
}
}
}
voidprintdir(intn)//根据DIR数值输出方向
{
switch(n)
{
case-1:
printf("东");break;
case-2:
printf("南");break;
case-3:
printf("东南");break;
case-4:
printf("东北");break;
case1:
printf("西");break;
case2:
printf("北");break;
case3:
printf("西北");break;
case4:
printf("西南");break;
default:
printf("error");
}
}
voidGPS1(graph&t,intcat,intstart,intdes)//寻找最短路径
{
inti,j,m,g;
intlmat[50][50][2],pb[50][50][50];
getlmat(t,cat,lmat);
getshortlmat(lmat,t,pb);
i=start;j=des;g=i;
printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
printf("%s到%s\n",t.spot[i].name,t.spot[j].name);
printf("从%s",t.spot[i].name);
for(m=0;pb[i][j][m]>=0;m++)
{
printf("向");
printdir(lmat[pb[i][j][m]][g][1]);
printf("%d米至%s",lmat[g][pb[i][j][m]][0],t.spot[pb[i][j][m]].name);
g=pb[i][j][m];
}
printf("向");
printdir(lmat[j][g][1]);
printf("%d米至%s",lmat[g][j][0],t.spot[j].name);
printf("\n道路类别:
");
if(cat==1)printf("车道\t");elseif(cat==2)printf("人行道\t");elseif(cat==3)printf("观景路径\t");
printf("总路程:
%d(m)\n",lmat[i][j][0]);
printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
}
voidgetxy(intx,inty,intdir,intdis,intbi,int&x1,int&y1)//通过坐标(x,y)得到与它方向为DIR距离为DIS和比例尺为BI的点坐标(x1,y1)
{
switch(dir)
{
case1:
y1=y;x1=x+dis/bi;break;
case2:
x1=x;y1=y+dis/bi;break;
case3:
x1=x+(dis/bi)*7/10;y1=y+(dis/bi)*7/10;break;
case4:
x1=x+(dis/bi)*7/10;y1=y-(dis/bi)*7/10;break;
case-1:
y1=y;x1=x-dis/bi;break;
case-2:
x1=x;y1=y-dis/bi;break;
case-3:
x1=x-(dis/bi)*7/10;y1=y-(dis/bi)*7/10;break;
case-4:
x1=x-(dis/bi)*7/10;y1=y+(dis/bi)*7/10;break;
}
}
intmax2(intx,inty)
{
return((x>y)?
x:
y);
}
intmin2(intx,inty)
{
return((xx:
y);
}
voidlinking(charg[100][100],intX,intY,intX1,intY1)//将(X,Y)和(X1,Y1)用'*'链接
{
intx,y,x1,y1;
if(Xelse{x=X1;x1=X;y=Y1;y1=Y;}
intk,i;
if(x==x1)
for(i=min2(y,y1);ig[i][x]='.';
else
{
k=10*(y1-y)/(x1-x);
for(i=0;ig[y+i*k/10][x+i]='.';
}
}
voidpt(charg[100][100],intx,inty,char*name)//在(x,y)点做一个带边框文字为name的tip
{
inti,len=strlen(name);
if(len%2)len++;
g[y][x-2]=shu[0];g[y][x-1]=shu[1];g[y+1][x-2]=zuox[0];g[y+1][x-1]=zuox[1];g[y-1][x-2]=zuos[0];g[y-1][x-1]=zuos[1];
for(i=0;i{
g[y-1][i+x]=heng[i%2];
g[y+1][i+x]=heng[i%2];
g[y][i+x]=name[i];
}
i=i+x-1;
g[y][i+1]=shu[0];g[y][i+2]=shu[1];g[y+1][i+1]=youx[0];g[y+1][i+2]=youx[1];g[y-1][i+1]=yous[0];g[y-1][i+2]=yous[1];
}
voidprintgraph(charg[100][100],intwei,inthei)//打印高hei宽wei的字符数组g
{
inti,j;
for(i=0;i{
for(j=0;j{printf("%c",g[i][j]);}
printf("\n");
}
}
voidDFSTip(charg[100][100],graph&t,intn,intxy[50][3],intbi)//深度遍历第n个节点,通过与它相连的边得到与他相连的节点坐标存入xy数组里,并在字符数组g中连接每个存在的路径比例尺为bi
{
intmark=0;
adj*tj=t.spot[n].firstedge;
while
(1)
{
if(tj->ivex==n)
{
if(!
xy[tj->jvex][0])
{
getxy(xy[n][1],xy[n][2],tj->info.dir,tj->info.len,bi,xy[tj->jvex][1],xy[tj->jvex][2]);
xy[tj->jvex][0]=1;
DFSTip(g,t,tj->jvex,xy,bi);
}
if(xy[tj->jvex][0]&&xy[n][1]>=0&&xy[n][1]<100&&xy[n][2]>=0&&xy[n][2]<=100&&xy[tj->jvex][1]>=0&&xy[tj->jvex][1]<100&&xy[tj->jvex][2]>=0&&xy[tj->jvex][2]<=100)
linking(g,xy[n][1],xy[n][2],xy[tj->jvex][1],xy[tj->jvex][2]);
if(!
(tj=tj->ilink))break;
}
elseif(tj->jvex==n)
{
if(!
xy[tj->ivex][0])
{
getxy(xy[n][1],xy[n][2],-tj->info.dir,tj->info.len,bi,xy[tj->ivex][1],xy[tj->ivex][2]);
xy[tj->ivex][0]=1;
DFSTip(g,t,tj->ivex,xy,bi);
}
if(xy[tj->ivex][0]&&xy[n][1]>=0&&xy[n][1]<100&&xy[n][2]>=0&&xy[n][2]<=100&&xy[tj->ivex][1]>=0&&xy[tj->ivex][1]<100&&xy[tj->ivex][2]>=0&&xy[tj->ivex][2]<=100)
linking(g,xy[n][1],xy[n][2],xy[tj->ivex][1],xy[tj->ivex][2]);
if(!
(tj=tj->jlink))break;
}
}
}
voidgetmap(charg[100][100],grapht,intbi,intxuhao)//由图t得