【数据结构实训】校园导游系统
[基本要求]
1、設(shè)計(jì)你的學(xué)校的校園平面圖,所含景點(diǎn)10-15個(gè)。以圖中頂點(diǎn)表示校園內(nèi)各景點(diǎn),存放景點(diǎn)名稱(chēng)、代號(hào)、簡(jiǎn)介等信息;以邊表示路徑,存放路徑長(zhǎng)度等相關(guān)信息。//存
√ 2、為來(lái)訪(fǎng)客人提供圖中任意景點(diǎn)相關(guān)信息的查詢(xún)。//輸出 √
3、為來(lái)訪(fǎng)客人提供圖中任意景點(diǎn)的問(wèn)路查詢(xún),即查詢(xún)?nèi)我鈨蓚€(gè)景點(diǎn)之間的一條最短的簡(jiǎn)單路徑。//最短路 √dijkstra
4、提供圖中任意景點(diǎn)問(wèn)路查詢(xún),即求任意兩個(gè)景點(diǎn)之間的所有路徑。//所有路徑 //√dfs
5、提供校園圖中多個(gè)景點(diǎn)的最佳訪(fǎng)問(wèn)路線(xiàn)查詢(xún),即求途經(jīng)這多個(gè)景點(diǎn)的最佳路徑。//多點(diǎn)最短路 √Floyd
6、區(qū)分汽車(chē)線(xiàn)路與步行線(xiàn)路。//兩個(gè)結(jié)構(gòu)體 √ 7、設(shè)計(jì)一實(shí)用的查詢(xún)界面和功能菜單。//多個(gè)函數(shù) √
[測(cè)試數(shù)據(jù)]
10
1 校門(mén)口 出入校園都需要經(jīng)過(guò)校門(mén)口
2 教學(xué)樓 學(xué)生學(xué)習(xí)的地方,書(shū)聲瑯瑯,學(xué)習(xí)氛圍濃重
3 女生宿舍 女生休息的地方
4 男生宿舍 男生休息的地方
5 食堂 學(xué)生和老師吃飯的地方
6 鵝卵石路 校園的偏僻小徑
7 亭子 冷清,一般沒(méi)有人來(lái)往
8 湖邊 湖面很大,不要靠近湖邊玩水或扔垃圾
9 停車(chē)場(chǎng) 校園里車(chē)輛停放的地方
10 操場(chǎng) 供師生們運(yùn)動(dòng)的地方
12
1 2 5
1 10 7
1 6 4
2 9 6
2 8 5
3 10 3
3 5 2
4 5 3
4 8 8
5 10 3
5 8 7
6 7 4
6
1 2 5
2 3 10
2 4 9
2 9 6
3 4 4
4 9 10
24
1 6 東
1 10 東南
1 2 西南
2 1 東北
2 8 南
2 9 西南
3 10 西北
3 5 西
4 5 北
4 8 西北
5 10 北
5 3 東
5 4 南
5 8 西
6 1 西
6 7 東
7 6 西
8 2 北
8 5 東
8 4 東南
9 2 東北
10 1 西北
10 3 東南
10 5 南
12
1 2 西南
2 1 東北
2 3 東偏南
2 4 南偏東
2 9 西南
3 2 西北
3 4 西南
4 9 西偏北
4 2 北偏西
4 3 東北
9 2 東北
9 4 東南
[選做內(nèi)容]
1、擴(kuò)充道路信息,如道路類(lèi)別(車(chē)道、人行道等)、沿途景色等,以至可按客人所需分別查詢(xún)?nèi)诵新窂胶蛙?chē)行路徑或觀(guān)察路徑。
2、擴(kuò)充每個(gè)景點(diǎn)的鄰接景點(diǎn)的方向等信息,使得路徑查詢(xún)結(jié)果能提供詳盡的導(dǎo)向信息。
3、實(shí)現(xiàn)校園導(dǎo)游圖的仿真界面。
[代碼實(shí)現(xiàn)]
//0!='0' #include<queue> #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<stack> using namespace std; #define scnaf scanf #define ll long long const int N=1e2+50; const int INF=0x3f3f3f3f; int head[2][N],cnt[2],n=10,m[2],f[2];//鏈?zhǔn)角跋蛐? 第一個(gè)以i為頂點(diǎn)的邊 邊的個(gè)數(shù) 路徑數(shù) 景點(diǎn)的個(gè)數(shù) 方位數(shù) | 0人1車(chē) int dfsv[N]={0},p[N],top=0,way;//dijkstra: 標(biāo)記是否入"棧"過(guò) 存路徑|"類(lèi)棧" 棧中元素?cái)?shù) int floydp[N],floydw[N][N],pathw[N],pcnt; //floyd: 多源最短路所需途徑景點(diǎn)代號(hào) floydw[i][j]從景點(diǎn)i到j(luò)需要途徑的代號(hào) 記錄多源最短路徑 記錄查找到的路徑上景點(diǎn)數(shù) void printff(); struct S {char name[20],intr[50],fang[2][15][10];//名字 簡(jiǎn)介 方向 }sce[N];//景點(diǎn)信息 struct ss {int next,to,w;//下一個(gè)以i為頂點(diǎn)的邊的位置 該邊的尾 該邊的權(quán)值 }e[2][N]; void add(int x,int y,int w,int flag)//添加無(wú)向邊 {e[flag][++cnt[flag]].to=y;e[flag][cnt[flag]].w=w;e[flag][cnt[flag]].next=head[flag][x];head[flag][x]=cnt[flag]; } void scene(int k)//查詢(xún)k景點(diǎn)信息 {printf(" 查詢(xún)景點(diǎn)代號(hào)為%d\n 名稱(chēng):%s\n 簡(jiǎn)介:%s\n",k,sce[k].name,sce[k].intr); } void dij(int x,int y,int flag)//單源點(diǎn)最短路->dijkstra {int d[N],v[N],path[N],i,j,k,t[N];//v[i]景點(diǎn)i被訪(fǎng)問(wèn)過(guò),d[i]景點(diǎn)x到景點(diǎn)i的最短距離,path[i]=j表明從x到i最后一段是i->jmemset(d,INF,sizeof(d));memset(path,INF,sizeof(path));memset(v,0,sizeof(v));d[x]=0;while(1){k=-1,j=INF;for(i=1;i<=n;i++)if(d[i]<j&&!v[i])//被訪(fǎng)問(wèn)到但沒(méi)有被選擇過(guò){k=i;j=d[i];}if(k==-1)//沒(méi)有連通點(diǎn)或者全部選擇結(jié)束break;v[k]=1;//要在進(jìn)循環(huán)前標(biāo)記,否則會(huì)反復(fù)訪(fǎng)問(wèn)k點(diǎn)for(i=head[flag][k];i;i=e[flag][i].next){if(!v[e[flag][i].to]&&((d[k]+e[flag][i].w)<d[e[flag][i].to])){d[e[flag][i].to]=d[k]+e[flag][i].w;path[e[flag][i].to]=k;}}}k=0,j=y;while(path[j]!=INF){t[++k]=path[j];j=path[j];}if(!k){printf("\n 您查詢(xún)的兩點(diǎn)之間不通,請(qǐng)重新輸入\n");return ;}printf("\n 兩景點(diǎn)最短路線(xiàn)為: ");for(i=k,t[0]=y;i>0;i--){printf(" %d",t[i]);printf(" %s ->",sce[t[i]].fang[flag][t[i-1]]);}printf(" %d",y);printf("\n 兩景點(diǎn)距離為: %d(單位/百米)\n",d[y]); } void priath(int p[],int top,int way,int flag)//打印路徑 {printf(" 路徑%d:",++way);int i;for(i=1;i<top;i++){printf(" %d ",p[i]);printf("%s ->",sce[p[i]].fang[flag][p[i+1]]);}printf(" %d\n",p[top]); } void dfsway(int x,int y,int flag,int top)//深搜所有路徑 {dfsv[x]=1;p[++top]=x;if(p[top]==y)priath(p,top,way,flag);for(int i=head[flag][x];i;i=e[flag][i].next)if(!dfsv[e[flag][i].to])dfsway(e[flag][i].to,y,flag,top);dfsv[x]=0;//遞歸. 當(dāng)退到棧內(nèi)點(diǎn)時(shí),已經(jīng)循環(huán)過(guò),所以所有點(diǎn)可以共用一個(gè)標(biāo)記數(shù)組top--; } void evway(int x,int y,int flag)//初始化"棧" {way=top=0;memset(dfsv,0,sizeof(dfsv));dfsway(x,y,flag,top);if(!way)printf("\n 您查詢(xún)的兩點(diǎn)之間不通,請(qǐng)重新輸入\n"); } void pathway(int l,int r)//遞歸回推路徑 {if(l==r)return ;if(floydw[l][r]==-1)pathw[++pcnt]=r;else{pathway(l,floydw[l][r]);pathway(floydw[l][r],r);} } void floyd(int flag)//處理多源最短距離 {int i,j,k,p,dp[N][N];// dp[i][j]從景點(diǎn)i到景點(diǎn)j的距離memset(dp,INF,sizeof(dp));memset(floydw,-1,sizeof(floydw));for(i=1;i<=n;i++)dp[i][i]=0;for(i=1;i<=n;i++){for(j=head[flag][i];j;j=e[flag][j].next)dp[i][e[flag][j].to]=e[flag][j].w;}for(k=1;k<=n;k++)//景點(diǎn)for(i=1;i<=n;i++)//遍歷數(shù)組松弛每對(duì)景點(diǎn)for(j=1;j<=n;j++)if((dp[i][k]+dp[k][j])<dp[i][j]){dp[i][j]=dp[i][k]+dp[k][j];floydw[i][j]=k;}for(i=2,k=1,pcnt=0;floydp[i];i++)//i是終點(diǎn) k是起點(diǎn) pcnt是{for(j=1,p=0;j<=pcnt;j++)if(floydp[i]==pathw[j])p=1;if(dp[floydp[k]][floydp[i]]==INF){printf(" 您查詢(xún)的地點(diǎn)不互通,請(qǐng)重新輸入\n");return ;}if(!p){pathway(floydp[k],floydp[i]);k=i;}}pathw[0]=floydp[1];//出發(fā)點(diǎn)for(i=0;i<pcnt;i++){printf("%d",pathw[i]);printf(" %s -> ",sce[pathw[i]].fang[flag][pathw[i+1]]);}printf("%d",pathw[i]); } int main() {int i,j,k,x,y,w,p,flag=0;printf("請(qǐng)輸入景點(diǎn)個(gè)數(shù)\n");scnaf("%d",&n);printf("\n請(qǐng)輸入景點(diǎn)信息(代號(hào) 名稱(chēng) 簡(jiǎn)介):\n");for(i=1;i<=n;i++)scnaf("%d%s%s",&j,&sce[j].name,&sce[j].intr);printf("\n請(qǐng)輸入景點(diǎn)步行路線(xiàn)數(shù):\n");scanf("%d",&m[0]);printf("\n請(qǐng)依次輸入景點(diǎn)步行路線(xiàn):\n");for(i=1;i<=m[0];i++){scnaf("%d%d%d",&x,&y,&w);add(x,y,w,0);add(y,x,w,0);}printf("\n請(qǐng)輸入景點(diǎn)汽車(chē)路線(xiàn)數(shù):\n");scanf("%d",&m[1]);printf("\n請(qǐng)依次輸入景點(diǎn)汽車(chē)路線(xiàn):\n");for(i=1;i<=m[1];i++){scnaf("%d%d%d",&x,&y,&w);add(x,y,w,1);add(y,x,w,1);}printf("\n請(qǐng)輸入步行方位數(shù):\n");scanf("%d",&f[0]);printf("\n請(qǐng)依次輸入景點(diǎn)間步行的方位:\n");for(i=1;i<=f[0];i++){scnaf("%d%d",&x,&y);scanf("%s",&sce[x].fang[0][y]);}printf("\n請(qǐng)輸入汽車(chē)方位數(shù):\n");scanf("%d",&f[1]);printf("\n請(qǐng)依次輸入景點(diǎn)間步行的方位:\n");for(i=1;i<=f[1];i++){scnaf("%d%d",&x,&y);scnaf("%s",&sce[x].fang[1][y]);}while(1){printf("請(qǐng)輸入:\n 0.退出\n 1.查詢(xún)?nèi)我饩包c(diǎn)信息\n 2.查詢(xún)?nèi)我鈨蓚€(gè)景點(diǎn)最短路線(xiàn)\n");printf(" 3.查詢(xún)?nèi)我鈨蓚€(gè)景點(diǎn)所有路線(xiàn)\n 4.查詢(xún)多個(gè)景點(diǎn)最佳路線(xiàn)\n 5.導(dǎo)游仿真圖\n");scanf("%d",&p);if(!p)break;switch(p){case 1:{printf("\n請(qǐng)輸入查詢(xún)景點(diǎn)的代號(hào):\n");scanf("%d",&k);scene(k);break;}case 2:{printf("\n請(qǐng)輸入查詢(xún)路線(xiàn)類(lèi)型:\n 0.步行\(zhòng)n 1.汽車(chē)\n");scanf("%d",&flag);printf("\n請(qǐng)輸入兩景點(diǎn)的代號(hào)(將默認(rèn)第一個(gè)數(shù)字為起點(diǎn)):\n");scnaf("%d%d",&x,&y);dij(x,y,flag);break;}case 3:{printf("\n請(qǐng)輸入查詢(xún)路線(xiàn)類(lèi)型:\n 0.步行\(zhòng)n 1.汽車(chē)\n");scnaf("%d",&flag);printf("\n請(qǐng)輸入兩景點(diǎn)代號(hào)(將默認(rèn)第一個(gè)數(shù)字為起點(diǎn)):\n");scnaf("%d%d",&x,&y);evway(x,y,flag);break;}case 4:{printf("\n請(qǐng)輸入查詢(xún)路線(xiàn)類(lèi)型:\n 0.步行\(zhòng)n 1.汽車(chē)\n");scnaf("%d",&flag);printf("\n請(qǐng)依次輸入景點(diǎn)代號(hào)(將默認(rèn)第一個(gè)數(shù)字為起點(diǎn)),輸入數(shù)字0結(jié)束\n");for(i=1;;i++){scanf("%d",&floydp[i]);if(!floydp[i])break;}floyd(flag);break;}case 5:printff();break;}}return 0; } void printff() {printf("\n步行導(dǎo)游仿真圖:\n");printf(" 1校門(mén)口***6鵝卵石路***7亭子\n");printf(" * * \n");printf(" * * \n");printf(" * * \n");printf(" 2教學(xué)樓 10操場(chǎng) \n");printf(" * * * \n");printf(" * * * \n");printf(" * * * \n");printf("9停車(chē)場(chǎng) 8湖邊*******5食堂***3女生宿舍\n");printf(" * * \n");printf(" ***** * \n");printf(" **4男生宿舍 \n");printf("\n\n汽車(chē)導(dǎo)游仿真圖:\n");printf(" 1校門(mén)口\n");printf(" * \n");printf(" * \n");printf(" * \n");printf(" 2教學(xué)樓 \n");printf(" * ***** \n");printf(" * ***** \n");printf(" * ***** \n");printf("9停車(chē)場(chǎng) *****3女生宿舍\n");printf(" **** ** \n");printf(" **** ** \n");printf(" ****4男生宿舍 \n"); }總結(jié)
以上是生活随笔為你收集整理的【数据结构实训】校园导游系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【数学建模暑期培训】Matlab数据分析
- 下一篇: ISIS的vsys(虚拟系统)