数据结构校园导游实验报告.docx
- 文档编号:5010043
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:33
- 大小:131.23KB
数据结构校园导游实验报告.docx
《数据结构校园导游实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构校园导游实验报告.docx(33页珍藏版)》请在冰豆网上搜索。
数据结构校园导游实验报告
数据结构上机实验报告
厦门大学信息科学与技术学院计算机系
姓名:
彭钰杰年级:
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;i for(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;i for(j=0;j for(k=0;k pb[i][j][k]=-1; for(time=0;time for(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((x x: y); } voidlinking(charg[100][100],intX,intY,intX1,intY1)//将(X,Y)和(X1,Y1)用'*'链接 { intx,y,x1,y1; if(X else{x=X1;x1=X;y=Y1;y1=Y;} intk,i; if(x==x1) for(i=min2(y,y1);i g[i][x]='.'; else { k=10*(y1-y)/(x1-x); for(i=0;i g[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得
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 校园 导游 实验 报告