第一篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)校園導(dǎo)游咨詢
9、校園導(dǎo)游咨詢 問題描述:
設(shè)計(jì)一個校園導(dǎo)游程序,為來訪的客人提供各種信息查詢服務(wù)。基本要求:
⑴設(shè)計(jì)華東交通大學(xué)的校園平面圖,所含景點(diǎn)不少于10個。以圖中頂點(diǎn)表示校內(nèi)各景點(diǎn),⑵存放景點(diǎn)名稱、代號、簡介等信息;以邊表示路徑,存放路徑長度等相關(guān)信息。⑶為來訪客人提供圖中任意景點(diǎn)相關(guān)信息的查詢。⑷為來訪客人提供圖中任意景點(diǎn)的問路查詢,即查詢?nèi)我鈨蓚€景點(diǎn)之間的一條最短的簡單路徑。
#include
//最大頂點(diǎn)個數(shù) #define INF 32767
//用32767表示∞ #include
//調(diào)用函數(shù)system改變字體顏色的頭文件
typedef int InfoType;#define MAXV 100
//最大頂點(diǎn)個數(shù) //以下定義鄰接矩陣類型 typedef struct {
int no;
//頂點(diǎn)編號
InfoType info;
//頂點(diǎn)其他信息 } VertexType;
//頂點(diǎn)類型 typedef struct
//圖的定義 {
int edges[MAXV][MAXV];//鄰接矩陣
int vexnum,arcnum;
//頂點(diǎn)數(shù),弧數(shù)
VertexType vexs[MAXV];//存放頂點(diǎn)信息 } MGraph;
void ecjtumap()//建立華東交通大學(xué)地圖
{ printf(“t|------------------------------|n”);printf(“t|
|n”);printf(“t|
|n”);printf(“t|
----------
|n”);printf(“t|
==============================| 國防生宿舍|
|n”);printf(“t|。
----------
|n”);printf(“t|。
。
|n”);printf(“t|。
。
|n”);printf(“t|。
。
|n”);printf(“t|。
。
|n”);printf(“t|。
。
|n”);printf(“t|
|南區(qū)四食堂|
----------
|n”);printf(“t|。
|南區(qū)禮堂 |
|n”);printf(“t|。
----------
|n”);printf(“t|。
。
|n”);printf(“t|。
。
|n”);printf(“t|。
--------。
|n”);printf(“t|
================| 校訓(xùn)牌|。。。。
|n”);printf(“t|
=
--------
|n”);printf(“t|
=。
|n”);printf(“t|
=。
|n”);printf(“t|
--------
---------
|n”);printf(“t|----| 南區(qū)后門 |---------| 南區(qū)大門 |------------------------|n”);printf(“t|
--------
---------
|n”);printf(“t|
---------
|n”);printf(“t|-------------------------| 北區(qū)大門 |------------------------|n”);printf(“t|
--------
|n”);printf(“t|。
--------------
|n”);printf(“t|
===========================| 15棟綜合教學(xué)樓 |
|n”);printf(“t|
=
--------------
|n”);printf(“t|
=。
|n”);printf(“t|
=。
|n”);printf(“t|
=。
|n”);printf(“t|
=。
|n”);printf(“t|
=
----------
|n”);printf(“t|
===============================| 經(jīng)管食堂 |
|n”);printf(“t|
=
----------
|n”);printf(“t|
=
=
|n”);printf(“t|
=
=
|n”);printf(“t|
-----------
=
|n”);printf(“t|
|軌道交通食堂|====================| 學(xué)生宿舍 |
|n”);printf(“t|
------------
|n”);printf(“t|
|n”);printf(“t|------------------------------|n”);printf(“n”);} void DispMat(MGraph g)
//輸出鄰接矩陣g,即輸出地圖各景點(diǎn)的圖的距離 { int i,j;for(i=0;i for(j=0;j if(g.edges[i][j]==INF) printf(“%3s”,“∞”);//這里分別用%3s和%3d控制輸出字符∞或數(shù)字寬度為3個字符 else printf(“%3d”,g.edges[i][j]);//這樣比較方便觀看景點(diǎn)的圖的鄰接矩陣g printf(“n”);} } void listmap()//建立 景點(diǎn)的相關(guān)信息的總瀏覽表 { printf(“t 華東交通大學(xué)景點(diǎn)一覽 nn”);printf(“t|--------|n”);printf(“t| 1:南區(qū)大門 |n”);printf(“t|--------|n”);printf(“t| 2:校訓(xùn)牌 |n”);printf(“t|--------|n”);printf(“t| 3:圖書館 |n”);printf(“t|--------|n”);printf(“t| 4:南區(qū)一食堂 |n”);printf(“t|--------|n”);printf(“t| 5:孔目湖 |n”);printf(“t|--------|n”);printf(“t| 6:北區(qū)大門 |n”);printf(“t|--------|n”);printf(“t| 7:15棟教學(xué)樓 |n”);printf(“t|--------|n”);printf(“t| 8:北區(qū)食堂 |n”);printf(“t|--------|n”);printf(“t| 9:科技樓 |n”);printf(“t|--------|n”);printf(“t| 10:北區(qū)籃球場 |n”);printf(“t|--------|n”);} void introduce()//根據(jù)上面的瀏覽表,對應(yīng)出相關(guān)信息 { int a=1;printf(“n”);printf(“請輸入要查看的景點(diǎn):n”);printf(“輸入1~10的數(shù)字選擇景點(diǎn),其他數(shù)字返回上一級n”);while(0 switch(a) {case 1:printf(“1:南區(qū)大門是進(jìn)入華東交通大學(xué)南區(qū)的正門n”);break; case 2:printf(“2:校訓(xùn)牌是激勵我們大學(xué)生積極向上n”);break; case 3:printf(“3:圖書館是給我們大學(xué)生豐富知識的海洋n”);break; case 4:printf(“4:南區(qū)一食堂是南區(qū)學(xué)生的吃飯的地方n”);break; case 5:printf(“5:孔目湖是華東交通大學(xué)最迷人的地方n”);break; case 6:printf(“6:北區(qū)大門是進(jìn)入華東交通大學(xué)北區(qū)的正門n”);break; case 7:printf(“7:15棟教學(xué)樓是一棟綜合型的教學(xué)樓n”);break; case 8:printf(“8:北區(qū)食堂是北區(qū)學(xué)生吃飯的地方n”);break; case 9:printf(“9:科技樓是大學(xué)生上機(jī)做實(shí)驗(yàn)的教學(xué)樓n”);break; case 10:printf(“10:北區(qū)籃球場是大學(xué)生鍛煉身體的地方n”);break; } } } void show_didian(int n)//根據(jù)算法求出的整型數(shù),對應(yīng)出地點(diǎn)//根據(jù) xx算法求出的數(shù)字,轉(zhuǎn)化為文字描述 { switch(n){case 0:printf(“1.南區(qū)大門”);break;case 1:printf(“2.校訓(xùn)牌”);break;case 2:printf(“3.圖書館 ”);break;case 3:printf(“4.南區(qū)一食堂”);break;case 4:printf(“5.孔目湖”);break;case 5:printf(“6.北區(qū)大門”);break;case 6:printf(“7.15棟教學(xué)樓”);break;case 7:printf(“8.北區(qū)食堂”);break;case 8:printf(“9.科技樓”);break;case 9:printf(“10.北區(qū)籃球場”);break;} } void ppath(int path[][MAXV],int i,int j)//求最短路徑經(jīng)過的地點(diǎn) { int k=path[i][j];if(k==-1)return;ppath(path,i,k);show_didian(k);printf(“->> ”);ppath(path,k,j);} void put_shortdistance(int x,int y,int A[][MAXV],int path[][MAXV],int n){ int i,j;for(i=0;i for(j=0;j if(A[i][j]==INF) { if(i!=j)printf(“從%d到%d沒有路徑n”,i,j); } else { if(i==x&&j==y) { printf(“最短路徑為:從--”); show_didian(i); printf(“--到--”); show_didian(j); printf(“--路徑為--:n”); show_didian(i);//輸出起點(diǎn) printf(“->>”); ppath(path,i,j);//求最短路徑經(jīng)過的中間路徑,若沒有則不輸出 show_didian(j);//輸出 終點(diǎn) printf(“nt路徑長度為:%dn”,A[i][j]); } } } void shortdistance(MGraph g,int x,int y)//求最短路徑用的是弗洛伊德算法 { int A[MAXV][MAXV],path[MAXV][MAXV];//path為中間路徑不包括 起點(diǎn) 終點(diǎn) int i,j,k,n=g.vexnum;for(i=0;i //給A數(shù)組置初值 for(j=0;j { A[i][j]=g.edges[i][j];path[i][j]=-1; } for(k=0;k //計(jì)算Ak { for(i=0;i for(j=0;j //這里的3個for循環(huán) if(A[i][j]>(A[i][k]+A[k][j]))//所以時間復(fù)雜度O(n3) { A[i][j]=A[i][k]+A[k][j];path[i][j]=k; } } put_shortdistance(x,y,A,path,n);} void menu(MGraph g)//建立 菜單 頁面,可以無數(shù)次選擇菜單,當(dāng)輸入5時退出系統(tǒng) { int m=1,x=1,y=1;//m的菜單選擇的功能x,y分別表示從x到y(tǒng)的問路查詢 while(m!=5){ printf(“ttt|------------------------|n”); printf(“ttt|----------菜單----------|n”); printf(“ttt| 1:查看地圖 |n”); printf(“ttt| 2:地圖詳解 |n”); printf(“ttt| 3:景點(diǎn)一覽表 |n”); printf(“ttt| 4:問路查詢 |n”); printf(“ttt| 5:退出 |n”); printf(“ttt|------------------------|n”); printf(“請輸入1~5的數(shù)字n”); scanf(“%d”,&m); switch(m) {case 1:ecjtumap();break; case 2:listmap(); introduce();break; case 3:listmap(); introduce(); printf(“n”);break; case 4:listmap(); printf(“請輸入起點(diǎn):”); scanf(“%d”,&x);x+=-1; printf(“請輸入終點(diǎn):”); scanf(“%d”,&y);y+=-1; shortdistance(g,x,y);break; case 5:printf(“ttt感想使用本系統(tǒng),歡迎下次繼續(xù)使用n”);break; } } } void main(){ system(“color 0a”);//輸出字體為綠色 int i,j;MGraph g;int A[MAXV][10]={ {INF, 1,INF,INF,INF, 1,INF,INF,INF,INF},{ 1,INF, 5, 6, 7,INF,INF,INF,INF,INF},{INF, 5,INF,INF, 2,INF,INF,INF,INF,INF},{INF, 6,INF,INF, 5,INF,INF,INF,INF,INF},{INF, 7, 2, 5,INF,INF,INF,INF,INF,INF},{ 1,INF,INF,INF,INF,INF, 3,INF, 5,INF},{INF,INF,INF,INF,INF, 3,INF, 2,INF,INF},{INF,INF,INF,INF,INF,INF, 2,INF, 8, 10},{INF,INF,INF,INF,INF, 5,INF, 8,INF, 2},{INF,INF,INF,INF,INF,INF,INF, 10, 2,INF}};g.vexnum=11;g.arcnum=11;for(i=0;i for(j=0;j g.edges[i][j]=A[i][j];printf(“n”);printf(“ttt華東交通大學(xué)導(dǎo)游咨詢系統(tǒng)n”);menu(g);//進(jìn)入導(dǎo)游系統(tǒng),執(zhí)行菜單功能 } 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)報(bào)告 ——實(shí)驗(yàn)六 簡單校園導(dǎo)游程序的設(shè)計(jì)與實(shí)現(xiàn) 本實(shí)驗(yàn)的目的是通過對校園導(dǎo)游程序的設(shè)計(jì)與實(shí)現(xiàn)來熟練掌握圖型結(jié)構(gòu)在實(shí)際問題中的應(yīng)用。 一、【問題描述】 當(dāng)人們到一個陌生的地方去旅游的時候可能會找一個導(dǎo)游為自己在游玩的過程中提供方便。導(dǎo)游可以提供很多服務(wù),比如介紹參觀景點(diǎn)的歷史背景等相關(guān)信息,推薦到下一個景點(diǎn)的最佳路徑,以及解答旅游者所提出的關(guān)于旅游經(jīng)典的相關(guān)問詢等等。對于新生剛剛來到校園,對校園環(huán)境不熟悉的情況也如此,一般都是高年級的學(xué)生充當(dāng)了“校園導(dǎo)游員”的角色,如果能夠提供一個程序讓新生或來訪的客人自主的通過與機(jī)器的“對話”來獲得相關(guān)的信息的話,將會節(jié)省大量的人力和時間。而且所提供的信息也能夠做到盡可能的準(zhǔn)確、詳盡。一個成功的校園導(dǎo)游程序可以替代現(xiàn)實(shí)生活中這些“校園導(dǎo)游員”,更方便了大家查詢校園相關(guān)的信息。 本次實(shí)驗(yàn)需要開發(fā)一個簡單的校園導(dǎo)游程序,程序的主體功能為: 1、顯示校園平面圖,方便用戶直觀的看到校園的全景示意圖,并確定自己的位置。 2、為用戶提供對平面圖中任意場所的相關(guān)信息的查詢。 3、為用戶提供對平面圖中任意場所的問路查詢。 二、【數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)】 由于各個場所通過校園中的道路相連,各個場所和連接它們的道路構(gòu)成了整個校園的地理環(huán)境,所以使用圖這種數(shù)據(jù)結(jié)構(gòu)對他們?nèi)ミM(jìn)行描述。以圖中的頂點(diǎn)表示校園內(nèi)各個場所,應(yīng)包含場所名稱、代號、簡介等信息;以邊表示連接各個場所的道路,應(yīng)包含道路的代號、路徑的長度等信息。頂點(diǎn)和邊均使用結(jié)構(gòu)體定義,整個圖的數(shù)據(jù)結(jié)構(gòu)可以采用教材中介紹的各種表示方法,例如帶權(quán)的鄰接矩陣。 三、【功能(函數(shù))設(shè)計(jì)】 1、顯示校園平面圖的功能模塊。 通過讀文件的方式將各個地點(diǎn)的信息讀入程序中.平面圖中應(yīng)醒目的標(biāo)識出場所的準(zhǔn)確名稱以備用戶查詢。河北大學(xué)校園導(dǎo)游的基本地點(diǎn)信息。 ***************歡迎進(jìn)入河北大學(xué)校園導(dǎo)游系統(tǒng)!**************-----------------------景點(diǎn)名稱--------------------------- 主樓 多功能館 毓秀園 圖書館 操場 留學(xué)生樓 七教 八教 九教 成教 南大門 北大門 一教 逸夫樓 博物館 物理樓 電信樓 化學(xué)樓 生科樓 建工樓 北院食堂 南院食堂 竹園 梅園 桂園 菊園 易百超市 北院生活園區(qū) ---------------------------地點(diǎn)的存儲 typedef struct Vertex//頂點(diǎn)結(jié)構(gòu)體 { int No;//地點(diǎn)編號 char name[20];//地點(diǎn)名稱 char info[1000];//地點(diǎn)簡介 }Vertex;typedef struct //無向圖結(jié)構(gòu)體 { Vertex view[Max_Vertex];int edges[Max_Vertex][Max_Vertex];//邊的鄰接矩陣 int vnum,anum;//頂點(diǎn)和邊的個數(shù) }Graph; 2、查詢?nèi)我鈭鏊南嚓P(guān)信息查詢的功能模塊。 此模塊接收用戶所輸入的場所名稱,并將場所的簡介信息反饋給用戶。查找出查詢的場所將其信息輸出,信息通過文本文件讀入 函數(shù)void introduction(Graph &G)實(shí)現(xiàn) 先通過strcpy進(jìn)行查找,再講找到頂點(diǎn)v1 G.view[v1].info輸出 3、任意場所的問路查詢的功能模塊。 void shortpath(Graph &G,int v0,int v1);此函數(shù)運(yùn)用克魯斯卡爾算法計(jì)算兩點(diǎn)間最短路徑。 void dispath(Graph &G)//查詢最短路徑 { ?shortpath(G, v0, v1); } 此模塊接收用戶所輸入的場所名稱,并在調(diào)用shortpath(G, v0, v1);計(jì)算出最短路徑相關(guān)項(xiàng)的信息反饋給用戶。 4、求單源點(diǎn)到其他各點(diǎn)的最短路徑的功能模塊。 此模塊計(jì)算并記錄從校園門口到各個場所的最短路徑。for(i=0;i 四、【界面設(shè)計(jì)】 本程序?yàn)榉奖阌脩羲O(shè)計(jì),由于使用的最終用戶大多對校園的情況并不熟悉,所以在圖中給出的任何提示信息一定要準(zhǔn)確,盡量的避免歧義。 五、【編碼實(shí)現(xiàn)】 #include char name[20];//地點(diǎn)名稱 char info[1000];//地點(diǎn)簡介 }Vertex;typedef struct //無向圖結(jié)構(gòu)體 { Vertex view[Max_Vertex]; int edges[Max_Vertex][Max_Vertex];//邊的鄰接矩陣 int vnum,anum;//頂點(diǎn)和邊的個數(shù) }Graph;void Creat(Graph &G){ ifstream infile(“view.txt”,ios::in); if(!infile) { cout<<“文件打開錯誤”< abort(); } int i,j,k,w; infile>>G.vnum; infile>>G.anum; //cout< for(i=0;i { infile>>G.view[i].No>>G.view[i].name>>G.view[i].info; } for(i=0;i { for(j=0;j G.edges[i][j]=Maxnum; } ifstream weight_file(“weight.txt”,ios::in); if(!weight_file) { cout<<“文件打開錯誤”< abort(); } for(k=0;k { weight_file>>i>>j>>w; i--; j--; G.edges[i][j]=w; G.edges[j][i]=G.edges[i][j]; } } void introduction(Graph &G){ char temp[20];cout<<“請輸入要查詢的景點(diǎn)名稱”< if(strcmp(G.view[i].name,temp)==0) { v1=i; count++; } } if(count!=1){ cout<<“輸入的名稱不存在”< return;} else { cout<<“該景點(diǎn)簡介為”< cout< return;} } void shortpath(Graph &G,int v0,int v1){ int P[100];float D[100];int i,j,w;int v,pre;float min; int final[Max_Vertex];for(v=0;v { final[v]=0; D[v]=G.edges[v0][v]; if(D[v] P[v]=v0; if(D[v]==Maxnum) P[v]=-2; } D[v0]=0;final[v0]=1;P[v0]=-1; for(i=1;i min=Maxnum; //min為當(dāng)前所知離源點(diǎn)的最近距離 for(w=0;w if(!final[w]) if(D[w] { j=w; //記憶此點(diǎn) min=D[w]; } final[j]=1; //離源點(diǎn)最近的j加入S集合 for(w=0;w //更新其它點(diǎn)地當(dāng)前最短路徑 if(!final[w] &&(min+G.edges[j][w] { D[w]=min+G.edges[j][w]; P[w]=j; //將w的前驅(qū)結(jié)點(diǎn)改為j } } if(P[v1]==-2) cout<<“max”< else { pre=P[v1]; cout< cout< cout< while(pre>0) { cout<<“←”< pre=P[pre]; } if(v0==0) cout<<“←”< else cout< cout< } } void dispath(Graph &G)//查詢最短路徑 { int v1,v0,i;int count=0;char temp1[20],temp2[20];cout<<“請輸入要查詢的兩個景點(diǎn)名稱”< for(i=0;i if(strcmp(G.view[i].name,temp1)==0) { v0=i; count++; } if(strcmp(G.view[i].name,temp2)==0) { v1=i; count++; } } if(count!=2){ cout<<“輸入的名稱不存在”< return;} else { shortpath(G,v0,v1); return;} } void main(){ Graph G;Creat(G);int i;char ch1; cout<<“t***************歡迎進(jìn)入河北大學(xué)校園導(dǎo)游系統(tǒng)!**************”< cout<<“t-----------------------景點(diǎn)名稱---------------------------”< for(i=0;i { if(i%4==0) { cout< cout< } else { cout< } } cout< cout<<“t---------------------------”< cout<<“t__________________________________________________________”< cout<<“tt 請選擇要進(jìn)行的操作”< cout<<“ tt 1.查詢景點(diǎn)信息”< cout<<“ tt 2:顯示大門到各個地點(diǎn)的最短路徑”< cout<<“ tt 3:查詢兩個景點(diǎn)之間的最短路徑”< cout<<“ tt 0:退出”< cout<<“t__________________________________________________________”< cout<<“請選擇(0~2):”; cin>>ch1; while(!(ch1<='3'&&ch1>='0')) { cout<<“數(shù)據(jù)輸入錯誤,請重新選擇(0~2):”; cin>>ch1; } switch(ch1) { case '1': introduction(G);break; case '2' : for(i=0;i shortpath(G,10,i); break; case '3' : dispath(G); break; } }while(ch1!=0);} 六、【運(yùn)行與測試】 ***************歡迎進(jìn)入河北大學(xué)校園導(dǎo)游系統(tǒng)!************** -----------------------景點(diǎn)名稱--------------------------- 主樓 多功能館 毓秀園 圖書館 操場 留學(xué)生樓 七教 八教 九教 成教 南大門 北大門 一教 逸夫樓 博物館 物理樓 電信樓 化學(xué)樓 生科樓 建工樓 北院食堂 南院食堂 竹園 梅園 桂園 菊園 易百超市 北院生活園區(qū) --------------------------- __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2):1 請輸入要查詢的景點(diǎn)名稱 主樓 該景點(diǎn)簡介為 是河北大學(xué)本部標(biāo)志性建筑,這H型高大的建筑,正對著河北大學(xué)校本部南院黑 校門,此樓于2001年建成。主要為教學(xué)、科研、辦公服務(wù)。 __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2):1 請輸入要查詢的景點(diǎn)名稱 哈哈 輸入的名稱不存在 __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2):2 南大門到主樓最短路徑為50米 主樓←南大門 南大門到多功能館最短路徑為60米 多功能館←南大門 南大門到毓秀園最短路徑為60米 毓秀園←圖書館←南大門 南大門到圖書館最短路徑為40米 圖書館←南大門 南大門到操場最短路徑為160米 操場←毓秀園←圖書館←南大門 南大門到留學(xué)生樓最短路徑為180米 留學(xué)生樓←操場←毓秀園←圖書館←南大門 南大門到七教最短路徑為115米 七教←桂園←毓秀園←圖書館←南大門 南大門到八教最短路徑為65米 八教←圖書館←南大門 南大門到九教最短路徑為70米 九教←圖書館←南大門 南大門到成教最短路徑為75米 成教←八教←圖書館←南大門 南大門到南大門最短路徑為0米 南大門 南大門到北大門最短路徑為25米 北大門←南大門 南大門到一教最短路徑為35米 一教←北大門←南大門 南大門到逸夫樓最短路徑為60米 逸夫樓←博物館←物理樓←北大門←南大門 南大門到博物館最短路徑為45米 博物館←物理樓←北大門←南大門 南大門到物理樓最短路徑為35米 物理樓←北大門←南大門 南大門到電信樓最短路徑為60米 電信樓←一教←北大門←南大門 南大門到化學(xué)樓最短路徑為50米 化學(xué)樓←物理樓←北大門←南大門 南大門到生科樓最短路徑為145米 生科樓←建工樓←化學(xué)樓←物理樓←北大門←南大門 南大門到建工樓最短路徑為100米 建工樓←化學(xué)樓←物理樓←北大門←南大門 南大門到北院食堂最短路徑為115米 北院食堂←化學(xué)樓←物理樓←北大門←南大門 南大門到南院食堂最短路徑為80米 南院食堂←八教←圖書館←南大門 南大門到竹園最短路徑為135米 竹園←七教←桂園←毓秀園←圖書館←南大門 南大門到梅園最短路徑為145米 梅園←七教←桂園←毓秀園←圖書館←南大門 南大門到桂園最短路徑為95米 桂園←毓秀園←圖書館←南大門 南大門到菊園最短路徑為125米 菊園←八教←圖書館←南大門 南大門到易百超市最短路徑為145米 易百超市←七教←桂園←毓秀園←圖書館←南大門 南大門到北院生活園區(qū)最短路徑為159米 北院生活園區(qū)←北院食堂←化學(xué)樓←物理樓←北大門←南大門 __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2): 請輸入要查詢的兩個景點(diǎn)名稱 主樓 七教 主樓到七教最短路徑為75米 七教←桂園←毓秀園←主樓 __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2):3 請輸入要查詢的兩個景點(diǎn)名稱 桌嘍 菊園 輸入的名稱不存在 __________________________________________________________ 請選擇要進(jìn)行的操作 1.查詢景點(diǎn)信息 2:顯示大門到各個地點(diǎn)的最短路徑 3:查詢兩個景點(diǎn)之間的最短路徑 0:退出 __________________________________________________________ 請選擇(0~2): 校園導(dǎo)航系統(tǒng) 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) 1引言 本概要設(shè)計(jì)說明書基于之前建立的軟件需求設(shè)計(jì)基礎(chǔ)上,對“蚌埠學(xué)院校園導(dǎo)航系統(tǒng)”做出概要分析。主要解決了實(shí)現(xiàn)該系統(tǒng)需求的程序模塊設(shè)計(jì)問題。包括如何把該系統(tǒng)劃分成若干個模塊、決定各個模塊之間的接口、模塊之間傳遞的信息,以及數(shù)據(jù)結(jié)構(gòu)、模塊結(jié)構(gòu)的設(shè)計(jì)等。在以下的概要設(shè)計(jì)報(bào)告中將對在本階段中對系統(tǒng)所做的所有概要設(shè)計(jì)進(jìn)行詳細(xì)的說明。 2程序設(shè)計(jì) 2.1設(shè)計(jì)時間 2015-06-01—2015-06-15 2.2設(shè)計(jì)目的 1.加深對《數(shù)據(jù)結(jié)構(gòu)》這門課程的進(jìn)一步理解與鞏固 2.通過課程設(shè)計(jì),培養(yǎng)自己的編程能力以及團(tuán)隊(duì)協(xié)作能力 3.加強(qiáng)自己對實(shí)際問題的分析能力,以及如何更好的將一些經(jīng)典的算法應(yīng)用于實(shí)際 2.3設(shè)計(jì)任務(wù) 該導(dǎo)航系統(tǒng)為參觀者提供校園主要建筑的基本信息及各建筑間的距離,同時通過該系統(tǒng)計(jì)算出所在位置到目的地的最短路徑。 2.4需求分析 1.程序體現(xiàn)的功能:(1)main()——主函數(shù) (2)navigate()——導(dǎo)航函數(shù) (3)pri()——打印校園平面圖函數(shù)(4)visit()——遞歸查找路線函數(shù) 2.正確輸入與輸出形式: 如: 執(zhí)行建筑查詢功能: ① 輸入為:sod 輸出為:該建筑所在的坐標(biāo)為7 8 種有花草和一些藝術(shù)標(biāo)記物 ② 輸入為:ld 輸出為:該位置沒有找到 你找的建筑沒有找到 執(zhí)行導(dǎo)航功能: 輸入為:請輸入你所在位置:gym 輸入你要的目的地:sod 輸出為:打印并給出所有可能走通的線路,計(jì)算出兩地間的最短路徑(距離) 執(zhí)行顯示最短路徑功能: 輸入為:請輸入你所在位置:sod 輸入你要的目的地:office 輸出為:其中最短路徑為: 平面圖中包含最短線路圖,其行走的距離為450米 2.5概要設(shè)計(jì) 2.5.1.設(shè)計(jì)思路和主要步驟 按照需求分析,首先我們先要把學(xué)校的整體布局給設(shè)計(jì)出來,即用一個二維數(shù)組char arr[17][22]表示學(xué)校的整體布局,并將每個建筑物用特殊的符號表示:/*2為墻壁 ■ A辦公樓? c教學(xué)區(qū)● g草坪? p操場▓ 0 路 b圖書館★ M門□ m 食堂○h為宿舍☆ T為體育館? l為實(shí)驗(yàn)室 ╳*/,然后要打印出學(xué)校的整體布局,設(shè)計(jì)一個pri(char,int)打印出學(xué)校的整體布局。 在學(xué)校里,最重要的是校園的導(dǎo)航系統(tǒng),這樣可以使人耳目一新的知道某個地方的某個地方的路徑,所以設(shè)計(jì)校園導(dǎo)航函數(shù)是必須的,因此我們設(shè)計(jì)void navigate(int x)函數(shù),在圖的應(yīng)用中,一個最重要的知識就是求最短路徑,我們并沒有用迪杰斯特拉的算法和弗洛伊德算法來實(shí)現(xiàn)這個功能,而是利用了迷宮求解問題中的遞歸意義來實(shí)現(xiàn)求最短路徑的功能void visit(int qiX,int qiY,int zhX,int zhY, int x)用于查找某地點(diǎn)到某地點(diǎn)的所有路徑,然后進(jìn)行比較,將最短路徑用函數(shù)void fuzhi(將最短路徑存放在一個數(shù)組中)。 2.5.2程序流程圖 2.6詳細(xì)設(shè)計(jì) 按照需求分析中的需求,和概要設(shè)計(jì)中的各流程圖的模塊,進(jìn)行詳細(xì)設(shè)計(jì),完善各流程的代碼,詳細(xì)設(shè)計(jì)如下: 2.6.1學(xué)校整體局部 char arr[17][22]={ /*2為墻壁 ■ A辦公樓? c教學(xué)區(qū)● g草坪? p操場▓ 0 路 b圖書館★ M門□ m 食堂○h為宿舍☆ T為體育館? l為實(shí)驗(yàn)室 ╳*/ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 {'2','2','2','2','2','2','2','2','2','2','2','2','2','M','2','2','2','2','2','2','2','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','0','0','0','0','0','0','0','0','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','g','g','g','g','g','g','g','g','0','2','2','2','0','2','2','2','2'}, {'M','0','0','0','0','g','g','g','g','g','g','g','g','0','0','0','0','0','0','0','m','2'}, {'2','l','l','l','0','0','0','0','0','0','0','0','0','0','h','h','h','h','h','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','0','0','0','0','0','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','0','2'}, {'2','0','0','0','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','0','0','0','0','0','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','M'}, {'2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'}, };4.3.2:校園建筑信息 struct Construct construct[]={ {3,4,“office”,“------n|一層為經(jīng)管系辦公室 |n|二層為外語系辦公室 |n|三層為文教系辦公室 |n|四層為計(jì)算機(jī)科學(xué)與技術(shù)系辦公室 |n|五樓為數(shù)理系辦公室 |n------n”},//辦公室 {4,8,“classroom”,“學(xué)生上課的主要區(qū)域”},//教學(xué)樓A {1,13,“northDoor”,“是學(xué)生經(jīng)常出入的門,人流量較大”},//北門 {5,17,“playground”,“體育課上課的場所,學(xué)生健身的去處?!眪,//操場 {6,1,“westDoor”,“是學(xué)校的正門,前方有一個面具很多的停車區(qū)”},//西門 {7,8,“sod”,“種有花草和一些藝術(shù)標(biāo)記物”},//草坪 {9,4,“l(fā)ab”,“學(xué)生動手實(shí)踐的教室”},//實(shí)驗(yàn)室 {9,7,“l(fā)ibrary”,“開放時間為:每天的8:00~21:00n是老師和學(xué)生學(xué)習(xí)的好去處”},//圖書館 {9,16,“Whostel”,“女生宿舍樓”},//宿舍樓A {7,19,“SdiningRoom”,“靠近女生宿舍的食堂,飯菜口味比較可口n人流量較大,但只在供餐時間較短”},//食堂A {12,16,“Mhostel”,“男生宿舍樓”},//宿舍樓B {15,16,“Thostel”,“教師公寓樓”},//宿舍樓C {13,19,“TdiningRoom ”,“靠近男生宿舍樓,供餐時間較長,隨時去隨時有飯”},//食堂B {14,4,“gym”,“內(nèi)部體育設(shè)施齊全,在里面可以打籃球、打排球、打羽毛球等等”},//體育館 {15,20,“eastDoor”,“學(xué)校正門,老師班車出入?!眪,//東門 {-1,-1,“No found”,“你找的建筑沒有找到”}, };2.6.2打印圖 void pri(char a[17][22],int bushu){ int i,j; for(i=0;i<17;i++){ for(j=0;j<22;j++){ switch(a[i][j]){ case '2':printf(“■”);break; case 'A':printf(“?”);break; case 'c':printf(“●”);break; case 'g':printf(“?”);break; case 'p':printf(“▓”);break; case '0':printf(“ ”);break; case 'b':printf(“★”);break; case 'M':printf(“□”);break; case 'm':printf(“○”);break; case 'h':printf(“☆”);break; case 'T':printf(“?”);break; case 'l':printf(“╳”);break; case '1':printf(“╬”);break; } } printf(“n”);} if(bushu>0){ printf(“其行走的距離為%d米n”,bushu*50);} printf(“備注:n■為墻壁,?辦公樓 ,●為教學(xué)區(qū), ? 為草坪,▓為操場,n”);printf(“★為圖書館, □為門,○為食堂,?為宿舍,?為體育館n╳為實(shí)驗(yàn)室n”);} 2.6.3導(dǎo)航函數(shù) void navigate(int x){ shortbushu=1000;/*用于記錄最短步數(shù)*/ struct Construct * qi;struct Construct * zh;int qiX, qiY,zhX,zhY;int c;int i=1;while(i==1){ printf(“請輸入你所在位置:”); qi=selectName(15); if((-1)==qi->x){ printf(“是否重新輸入你所在地:(1/0)n”); scanf(“%d”,&c); if(c==1){ i=1;}else{ return;} } else i=0;}; i=1;while(i==1){ printf(“輸入你要的目的地:”); zh=selectName(15); if((-1)==zh->x){ printf(“是否重新輸入你的目的地:(1/0)n”);scanf(“%d”,&c); if(c==1){ i=1;}else{ return;} } else i=0;} qiX=qi->x;qiY=qi->y;zhX=zh->x;zhY=zh->y;num=1;visit(qiX,qiY,zhX,zhY,x); printf(“其中最短路徑為:n”);pri(jilu,shortbushu);} 2.6.4查找路徑 void visit(int qiX,int qiY,int zhX,int zhY, int x){ //x為標(biāo)志,用于控制要不要顯示所有的路徑 當(dāng)其非0是顯示所有的路徑 char n=arr[qiX][qiY];arr[qiX][qiY]='1';bushu++;if(qiX==zhX&&qiY==zhY){ if(x){ printf(“第%d條線路n”,(num++)); pri(arr,bushu); } if(shortbushu>bushu){ shortbushu=bushu; fuzhi(); } } if(arr[qiX][qiY+1]=='0')visit(qiX,qiY+1,zhX,zhY,x);if(arr[qiX+1][qiY]=='0')visit(qiX+1,qiY,zhX,zhY,x);if(arr[qiX][qiY-1]=='0')visit(qiX,qiY-1,zhX,zhY,x);if(arr[qiX-1][qiY]=='0')visit(qiX-1,qiY,zhX,zhY,x);arr[qiX][qiY]=n;bushu--;} 2.6.5記錄最短路徑 void fuzhi(){ int i,j;for(i=0;i<17;i++){ for(j=0;j<22;j++){ jilu[i][j]=arr[i][j]; } } } 3調(diào)試分析 4附錄 程序源代碼: #include char jilu[17][22];/*用于記錄最短路徑*/ void fuzhi();/*用于給最短路徑賦值*/ int shortbushu=1000;/*用于記錄最短步數(shù)*/ int num=1;/*記錄多少條路*/ int bushu=0;/*記錄走了多遠(yuǎn)*/ struct Construct selectName(int *a,int n);/*根據(jù)名字查詢位置*/ void navigate(int x);/*導(dǎo)航*/ void pri(char [][22],int);//打印圖 void add();//增加建筑信息 void visit(int ,int,int,int,int);//遞歸查找路線 char arr[17][22]={ /*2為墻壁 ■ A辦公樓? c教學(xué)區(qū)● g草坪? p操場▓ 0 路 b圖書館★ M門□ m 食堂○h為宿舍☆ T為體育館? l為實(shí)驗(yàn)室 ╳*/ // 0 7 11 12 13 14 15 16 17 18 19 20 21 {'2','2','2','2','2','2','2','2','2','2','2','2','2','M','2','2','2','2','2','2','2','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','c','c','c','c','c','c','c','c','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','0','0','0','0','0','0','0','0','0','2','p','p','p','p','p','p','2'}, {'2','A','A','A','0','g','g','g','g','g','g','g','g','0','2','2','2','0','2','2','2','2'}, {'M','0','0','0','0','g','g','g','g','g','g','g','g','0','0','0','0','0','0','0','m','2'}, {'2','l','l','l','0','0','0','0','0','0','0','0','0','0','h','h','h','h','h','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','0','0','0','0','0','0','m','2'}, {'2','l','l','l','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','0','2'}, {'2','0','0','0','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','0','0','0','0','0','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','b','b','b','b','b','b','b','b','0','h','h','h','h','h','0','m','2'}, {'2','T','T','T','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','M'}, {'2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'}, };struct Construct{ int x;int y;char name[25];char miaoshu[10000];};struct Construct construct[]={ {3,4,“office”,“------n|一層為經(jīng)管系辦公室 |n|二層為外語系辦公室 |n|三層為文教系辦公室 |n|四層為計(jì)算機(jī)科學(xué)與技術(shù)系辦公室 |n|五樓為數(shù)理系辦公室 |n------n”},//辦公室 {4,8,“classroom”,“學(xué)生上課的主要區(qū)域”},//教學(xué)樓A {1,13,“northDoor”,“是學(xué)生經(jīng)常出入的門,人流量較大”},//北門 {5,17,“playground”,“體育課上課的場所,學(xué)生健身的去處?!眪,//操場 {6,1,“westDoor”,“是學(xué)校的正門,前方有一個面具很多的停車區(qū)”},//西門 {7,8,“sod”,“種有花草和一些藝術(shù)標(biāo)記物”},//草坪 {9,4,“l(fā)ab”,“學(xué)生動手實(shí)踐的教室”},//實(shí)驗(yàn)室 {9,7,“l(fā)ibrary”,“開放時間為:每天的8:00~21:00n是老師和學(xué)生學(xué)習(xí)的好去處”},//圖書館 {9,16,“Whostel”,“女生宿舍樓”},//宿舍樓A {7,19,“SdiningRoom”,“靠近女生宿舍的食堂,飯菜口味比較可口n人流量較大,但只在供餐時間較短”},//食堂A {12,16,“Mhostel”,“男生宿舍樓”},//宿舍樓B {15,16,“Thostel”,“教師公寓樓”},//宿舍樓C {13,19,“TdiningRoom ”,“靠近男生宿舍樓,供餐時間較長,隨時去隨時有飯”},//食堂B {14,4,“gym”,“內(nèi)部體育設(shè)施齊全,在里面可以打籃球、打排球、打羽毛球等等”},//體育館 {15,20,“eastDoor”,“學(xué)校正門,老師班車出入。”},//東門 {-1,-1,“No found”,“你找的建筑沒有找到”}, };void ar(){ int m,n;for(m=0;m<17;m++){ for(n=0;n<22;n++){ printf(“%c”,arr[m][n]); } printf(“n”);} } struct Construct * selectName(int n)/*根據(jù)名字查詢位置*/{ int i;char name[15];scanf(“%s”,&name);for(i=0;i if(strcmp(construct[i].name,name)==0){ return & construct[i]; } } printf(“給位置沒有找到n”);return & construct[15];} int main(){ int i; int n=15;struct Construct * jianzhu;while(1){ printf(“歡迎來到蚌埠學(xué)院,我們將為你提供貼心的導(dǎo)航服務(wù)n”); printf(“*********************************************n”); printf(“ 1.學(xué)校整體布局n”); printf(“ 2.建筑查詢n”); printf(“ 3.導(dǎo)航n”); printf(“ 4.顯示最短路徑n”); printf(“ 5.退出n”); printf(“*********************************************n”); scanf(“%d”,&i); switch(i){ case 1: printf(“查詢位置n”); pri(arr,0); break; case 2: printf(“請輸入查詢建筑的名稱:n”); jianzhu=selectName(n); if(-1!=jianzhu->x) printf(“該建筑所在的坐標(biāo)為%d %dn”,jianzhu->x,jianzhu->y); printf(“%sn”,jianzhu->miaoshu); break; case 3: printf(“導(dǎo)航n”); navigate(1); break; case 4: printf(“其中最短路徑為:n”); navigate(0); //pri(jilu,shortbushu); break; case 5: printf(“退出”); exit(0); break; } }; return 0;} void navigate(int x){ shortbushu=1000;/*用于記錄最短步數(shù)*/ struct Construct * qi;struct Construct * zh;int qiX, qiY,zhX,zhY;int c;int i=1; while(i==1){ printf(“請輸入你所在位置:”); qi=selectName(15); if((-1)==qi->x){ printf(“是否重新輸入你所在地:(1/0)n”); scanf(“%d”,&c); if(c==1){ i=1; }else{ return; } } else i=0;}; i=1;while(i==1){ printf(“輸入你要的目的地:”); zh=selectName(15); if((-1)==zh->x){ printf(“是否重新輸入你的目的地:(1/0)n”); scanf(“%d”,&c); if(c==1){ i=1; }else{ return; } } else i=0;} qiX=qi->x;qiY=qi->y; zhX=zh->x; zhY=zh->y; num=1; visit(qiX,qiY,zhX,zhY,x); printf(“其中最短路徑為:n”);pri(jilu,shortbushu); } /*2為墻壁 ■ A辦公樓? c教學(xué)區(qū)● g草坪? p操場▓ 0 路 b圖書館★ M門 □ m 食堂○h為宿舍? T為體育館?*/ void pri(char a[17][22],int bushu){ int i,j; for(i=0;i<17;i++){ for(j=0;j<22;j++){ switch(a[i][j]){ case '2':printf(“■”);break; case 'A':printf(“?”);break; case 'c':printf(“●”);break; case 'g':printf(“?”);break; case 'p':printf(“▓”);break; case '0':printf(“ ”);break; case 'b':printf(“★”);break; case 'M':printf(“□”);break; case 'm':printf(“○”);break; case 'h':printf(“☆”);break; case 'T':printf(“?”);break; case 'l':printf(“╳”);break; case '1':printf(“╬”);break; } } printf(“n”);} if(bushu>0){ printf(“其行走的距離為%d米n”,bushu*50);} printf(“備注:n■為墻壁,?辦公樓 ,●為教學(xué)區(qū), ? 為草坪,▓為操場,n”);printf(“★為圖書館, □為門,○為食堂,?為宿舍,?為體育館n╳為實(shí)驗(yàn)室n”); } void visit(int qiX,int qiY,int zhX,int zhY, int x){ //x為標(biāo)志,用于控制要不要顯示所有的路徑 當(dāng)其非0是顯示所有的路徑 char n=arr[qiX][qiY];arr[qiX][qiY]='1';bushu++;if(qiX==zhX&&qiY==zhY){ if(x){ printf(“第%d條線路n”,(num++)); pri(arr,bushu); } if(shortbushu>bushu){ shortbushu=bushu; fuzhi(); } } if(arr[qiX][qiY+1]=='0')visit(qiX,qiY+1,zhX,zhY,x);if(arr[qiX+1][qiY]=='0')visit(qiX+1,qiY,zhX,zhY,x);if(arr[qiX][qiY-1]=='0')visit(qiX,qiY-1,zhX,zhY,x);if(arr[qiX-1][qiY]=='0')visit(qiX-1,qiY,zhX,zhY,x);arr[qiX][qiY]=n;bushu--;} void fuzhi(){ int i,j;for(i=0;i<17;i++){ for(j=0;j<22;j++){ jilu[i][j]=arr[i][j]; } } } 總結(jié) 此次課程設(shè)計(jì)相對于我來說,難度較大,相對于這個學(xué)期寫的那些小算法來說,這個課程設(shè)計(jì)能充分發(fā)揮出學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)后的能力;而相對于之前做的設(shè)計(jì)性實(shí)驗(yàn),又有了實(shí)際的應(yīng)用,現(xiàn)實(shí)應(yīng)用度增加。 從接觸C語言編程到現(xiàn)在,我就覺得:編程不是簡簡單單的寫出程序,更多的是處理出現(xiàn)的語法和邏輯錯誤。在這次課程設(shè)計(jì)中,我深刻的體會到 編程不是一種簡單的事,編程不但需要耐心,更需要細(xì)心。編出大體的程序架構(gòu),花費(fèi)了我的時間并不多,但我很多時間是用在調(diào)試和測試數(shù)據(jù)上!有些現(xiàn)在看著簡單的語法錯誤,一時竟然無從下手。我想,這和我C語言基礎(chǔ)薄弱有很大關(guān)系,以后要加強(qiáng)認(rèn)識。 總的來說,這次課程設(shè)計(jì),讓我學(xué)了很多,總結(jié)了很多! 參考文獻(xiàn) [1] 嚴(yán)蔚敏,吳偉民.數(shù)據(jù)結(jié)構(gòu)(C語言版)[M].北京 清華大學(xué)出版社,2007 [2] 譚浩強(qiáng).C程序設(shè)計(jì)(第三版)[M].北京 清華大學(xué)出版社,2007 [3] 譚浩強(qiáng).C程序設(shè)計(jì)題解與上機(jī)指導(dǎo)(第三版)[M].北京 清華大學(xué)出版社,2007 [4] 嚴(yán)蔚敏,吳偉民,米 寧.數(shù)據(jù)結(jié)構(gòu)題集(C語言版)[M].北京 清華大學(xué)出版社,2007 [5] 互聯(lián)網(wǎng)的相關(guān)信息和內(nèi)容 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 一、設(shè)計(jì)題目 校園導(dǎo)游咨詢 二、需求分析 (1)設(shè)計(jì)你的學(xué)校的校園平面圖,所含景點(diǎn)不少于10個。以圖中頂點(diǎn)表示學(xué)校各景點(diǎn),存放景點(diǎn)名稱、代號、簡介等信息;以邊表示路徑,存放路徑長度等相關(guān)信息。 (2)為來訪客人提供圖中任意景點(diǎn)的問路查詢,即查詢?nèi)我鈨蓚€景點(diǎn)之間的一條最短的簡單路徑。 (3)為來訪客人提供圖中任意景點(diǎn)相關(guān)信息的查詢。(4)界面美觀,方便使用。通過主菜單操作。 三、總體設(shè)計(jì) 3.1 設(shè)計(jì)思路 設(shè)計(jì)一個校園導(dǎo)游系統(tǒng),應(yīng)用到數(shù)據(jù)結(jié)構(gòu)中學(xué)到的圖的建立,各景點(diǎn)應(yīng)存在一個圖中,而計(jì)算不重復(fù)路線的時候需要應(yīng)用到弗洛伊德圖的遍歷。計(jì)算倆景點(diǎn)間最短路徑應(yīng)用到最小生成樹的遍歷。 景點(diǎn)數(shù)據(jù)裝在一個圖中,能夠輸入圖的頂點(diǎn)和邊的信息,并存儲到相應(yīng)存儲結(jié)構(gòu)中然后輸出圖的鄰接矩陣。 鄰接矩陣是表示頂點(diǎn)之間相鄰關(guān)系。 生成樹是指:如果G是一個圖,這個圖的生成子圖T是樹,那么可以說T為G的生成樹。一個圖有生成樹當(dāng)且僅當(dāng)這個圖連通??赏ㄟ^求該網(wǎng)絡(luò)的最小生成樹達(dá)到求解線路或總代價(jià)最小的最佳方案。 弗洛伊德算法是通過一個圖的權(quán)值矩陣求出它的每兩點(diǎn)間的最短路徑矩陣。它是從圖的帶權(quán)鄰接矩A=[a(i,j)] n×n開始,遞歸地進(jìn)行n次更新,即由矩陣D(0)=A,按一個公式,構(gòu)造出矩陣D(1);又用同樣地公式由D(1)構(gòu)造出D(2);??;最后又用同樣的公式由D(n-1)構(gòu)造出矩陣D(n)。矩陣D(n)的i行j列元素便是i號頂點(diǎn)到j(luò)號頂點(diǎn)的最短路徑長度,稱D(n)為圖的距離矩陣,同時還可引入一個后繼節(jié)點(diǎn)矩陣path來記錄兩點(diǎn)間的最短路徑。3、2系統(tǒng)功能設(shè)計(jì) 本系統(tǒng)除了有主程序模塊外還有3個子功能菜單。3個子功能的設(shè)計(jì)描述如下。(1)學(xué)校景點(diǎn)介紹 學(xué)校景點(diǎn)介紹由函數(shù)introduce()實(shí)現(xiàn)。當(dāng)用戶選擇該功能,系統(tǒng)即能輸出學(xué)校全部景點(diǎn)的信息:包括景點(diǎn)編號、景點(diǎn)名稱及景點(diǎn)簡介。 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 (2)查看兩景點(diǎn)間最短路徑 查看兩景點(diǎn)間最短路徑由函數(shù)shortestdistance()實(shí)現(xiàn)。該功能采用弗洛伊德(Floyd)算法實(shí)現(xiàn)。當(dāng)用戶選擇該功能,系統(tǒng)能根據(jù)用戶輸入的起始景點(diǎn)及目的地景點(diǎn)編號,查詢?nèi)我鈨蓚€景點(diǎn)之間的最短路徑線路及距離。 (3)退出 即退出校園導(dǎo)游系統(tǒng),由exit(0)函數(shù)實(shí)現(xiàn)。3、3 模塊間調(diào)用關(guān)系 主程序模塊 (界面) 景點(diǎn)最短路徑查詢 景點(diǎn)信息查詢 退出 四、詳細(xì)設(shè)計(jì) 4、1數(shù)據(jù)存儲 (1)無向帶權(quán)圖(無向網(wǎng))的定義 int i,j; char k; for(i=0;i<=n;i++) for(j=0;j<=n;j++) { cost[i][j]=INT_MAX; } cost[1][3]=cost[3][1]=2; cost[2][3]=cost[3][2]=1; cost[2][4]=cost[4][2]=2; cost[3][10]=cost[10][3]=4; cost[1][10]=cost[10][1]=4; cost[2][10]=cost[10][2]=4; cost[4][10]=cost[10][4]=4; cost[1][4]=cost[4][1]=5; cost[4][5]=cost[5][4]=3; cost[4][9]=cost[9][4]=4; 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 cost[5][9]=cost[9][5]=8;cost[5][7]=cost[7][5]=4;cost[5][6]=cost[6][5]=2;cost[6][7]=cost[7][6]=1;cost[7][8]=cost[8][7]=3;cost[8][6]=cost[6][8]=4;cost[1][1]=cost[2][2]=cost[3][3]=cost[4][4]=cost[5][5]=0;cost[6][6]=cost[7][7]=cost[8][8]=cost[9][9]=cost[10][10]=0; (2)全局變量定義 #define INT_MAX 10000 #define n 10 int cost[n][n]; /* 邊的值*/ int shortest[n][n]; /* 兩點(diǎn)間的最短距離*/ int path[n][n]; /* 經(jīng)過的景點(diǎn)*/ 4、2主程序模塊 用于作為界面,顯示校園景點(diǎn)和概況描述,提供各子模塊的連接 如上圖所示 程序設(shè)計(jì) while(1) { printf(“----------------歡迎使用中北大學(xué)導(dǎo)游系統(tǒng)!----------------n”); printf(“1.景點(diǎn)信息查詢???請按 i(introduc)鍵n”); printf(“2.景點(diǎn)最短路徑查詢?請按 s(shortestdistance)鍵n”); printf(“3.退出系統(tǒng)?????請按 e(exit)鍵n”); printf(“學(xué)校景點(diǎn)列表:n”); printf(“1:學(xué)校南門 ”); printf(“2:學(xué)生公寓 ”); printf(“3:柏林園 ”); printf(“4:餐廳 ”); printf(“5:體育館n”); printf(“6:圖書館 ”); printf(“7:重點(diǎn)實(shí)驗(yàn)室 ”); printf(“8:主樓 ”); printf(“9:科藝苑 ”); printf(“10:國防生公寓n”); printf(“請選擇服務(wù):”); scanf(“n%c”,&k); 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 switch(k) { case 'i': printf(“進(jìn)入景點(diǎn)信息查詢:”); introduce(); break; case 's': printf(“進(jìn)入最短路徑查詢:”); shortestdistance(); break; case 'e': exit(0); default: printf(“輸入信息錯誤!n請輸入字母i或s或e.n”); break; } } 4、3景點(diǎn)信息查詢模塊 在主菜單下,用戶輸入i回車,根據(jù)屏幕提示輸入一個要查詢的景點(diǎn)編號3回車后,運(yùn)行結(jié)果如上圖所示。 不足之處:僅能根據(jù)景點(diǎn)編號進(jìn)行查詢,可以增加根據(jù)景點(diǎn)名進(jìn)行查詢的功能。 程序設(shè)計(jì) void introduce(){/*景點(diǎn)介紹*/ int a; printf(“您想查詢哪個景點(diǎn)的詳細(xì)信息?請輸入景點(diǎn)編號:”); scanf(“%d”,&a); getchar(); printf(“n”); switch(a) { case 1: printf(“1:學(xué)校南門nn 學(xué)校的正門,前面豎立著一尊彭德華的石 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 像,氣勢宏偉。nn”);break; case 2: printf(“2:學(xué)生公寓集中的地方。nn”);break; case 3: printf(“3:柏林園nn 晨讀鍛煉得地方。nn”);break; case 4: printf(“4:餐廳nn 學(xué)生老師就餐的地方nn”);break; case 5: printf(“5:體育館nn 體育館nn 學(xué)生上體育課及運(yùn)動的場地,設(shè)有田徑場、足球場、籃球場等。nn”);break; case 6: printf(“6:圖書館nn 學(xué)校信息資源中心,內(nèi)設(shè)大量的自習(xí)室。nn”);break; case 7: printf(“7:重點(diǎn)實(shí)驗(yàn)室nn 我校的研究科研中心nn”);break; case 8: printf(“8:主樓nn 學(xué)校行政辦公的主樓。nn”);break; case 9: printf(“9:科藝苑nn 有咖啡廳和放映室。nnn”);break; case 10: printf(“10: 國防生公寓nn 國防生居住地地方。nn”);break; default: printf(“景點(diǎn)編號輸入錯誤!請輸入1->10的數(shù)字編號!nn”);break; } }/*introduce*/ 4、4景點(diǎn)最短路徑查詢模塊 在主菜單下,用戶輸入3回車,根據(jù)屏幕提示輸入一個出發(fā)景點(diǎn)編號及目的地景點(diǎn)號:6“,”3回車后,運(yùn)行結(jié)果如上圖所示。 不足之處:只能看到最短路徑編號,但不知具體名稱,設(shè)計(jì)還不夠人性化。 程序設(shè)計(jì)(由floyed()和display(i,j)兩個子模塊完成)void floyed(){/*用floyed算法求兩個景點(diǎn)的最短路徑*/ 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 int i,j,k; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { shortest[i][j]=cost[i][j]; path[i][j]=0; } for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(shortest[i][j]>(shortest[i][k]+shortest[k][j])) {/*用path[][]記錄從i到j(luò)的最短路徑上點(diǎn)j的前驅(qū)景點(diǎn)的序號*/ shortest[i][j]=shortest[i][k]+shortest[k][j]; path[i][j]=k; path[j][i]=k; } }/*floyed*/ void display(int i,int j){/* 打印兩個景點(diǎn)的路徑及最短距離 */ int a,b; a=i; b=j; printf(“您要查詢的兩景點(diǎn)間最短路徑是:nn”); if(shortest[i][j]!=INT_MAX) { if(i { printf(“%d”,b); while(path[i][j]!=0) {/* 把i到j(luò)的路徑上所有經(jīng)過的景點(diǎn)按逆序打印出來*/ printf(“<-%d”,path[i][j]); if(i j=path[i][j]; else i=path[j][i]; } printf(“<-%d”,a); printf(“nn”); printf(“(%d->%d)最短距離是:%d米nn”,a,b,shortest[a][b]); } else { printf(“%d”,a); while(path[i][j]!=0) {/* 把i到j(luò)的路徑上所有經(jīng)過的景點(diǎn)按順序打印出來*/ printf(“->%d”,path[i][j]); 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 if(i j=path[i][j]; else i=path[j][i]; } printf(“->%d”,b); printf(“nn”); printf(“(%d->%d)最短距離是:%5d米nn”,a,b,shortest[a][b]); } } else printf(“輸入錯誤!不存在此路!nn”); printf(“n”);}/*display*/ 4、5退出 在主菜單下,用戶輸入e回車,即退出校園導(dǎo)游系統(tǒng)。 五、設(shè)計(jì)總結(jié)5、1用戶手冊 1.本程序執(zhí)行文件為:湖北第二師范學(xué)院校園導(dǎo)游系統(tǒng).exe 2.進(jìn)入本系統(tǒng)之后,隨即顯示系統(tǒng)主菜單界面。用戶可在該界面下輸入各子菜單前對應(yīng)的數(shù)字并按回車,執(zhí)行相應(yīng)子菜單命令。 3.查詢景點(diǎn)信息都是通過輸入景點(diǎn)編號并按回車實(shí)現(xiàn),兩個景點(diǎn)號之間用空格隔開。進(jìn)入本系統(tǒng)后,建議先選擇子菜單1――學(xué)校景點(diǎn)介紹,以了解景點(diǎn)名稱和景點(diǎn)編號的對應(yīng)關(guān)系。5、2心得體會 通過本次課程設(shè)計(jì)實(shí)驗(yàn),使我更能熟練地掌握c語言和數(shù)據(jù)結(jié)構(gòu)等知識的綜合運(yùn) 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 用。當(dāng)然在課程設(shè)計(jì)期間,也遇到了大大小小的一些問題,是我看到了自己的不足之處,使我認(rèn)識到在以后的學(xué)習(xí)中要善于發(fā)現(xiàn)自己的不足,找出自己的薄弱環(huán)節(jié),以便能夠更好的去鞏固所學(xué)的。 本次設(shè)計(jì)中要求求最短路徑,不重復(fù)走完一個圖,就必須了解最短路徑的算發(fā)和圖的遍歷。在拿到題目時,通過查找相關(guān)的資料才回憶起這兩種方法的具體算法。根據(jù)程序的具體要求來設(shè)計(jì)算法。在選用存儲方法是,要盡量選用時間復(fù)雜度較小的方法,這樣能夠節(jié)省程序執(zhí)行時間,提高查詢效率。 課程設(shè)計(jì)中所使用的計(jì)算機(jī)語言其使用范圍比較廣闊,在很多編程中都可以用到,所以無論以后我們從事計(jì)算機(jī)編程、軟件設(shè)計(jì)還是硬件、網(wǎng)絡(luò)等領(lǐng)域,都應(yīng)該學(xué)會、學(xué)精一門編程語言,這對我們以后的學(xué)習(xí)和工作有很大的幫助。 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 附錄 /*包含頭文件*/ #include /*定義符號常量*/ #define INT_MAX 10000 #define n 10 /*定義全局變量*/ int cost[n][n];/* 邊的值*/ int shortest[n][n];/* 兩點(diǎn)間的最短距離*/ int path[n][n];/* 經(jīng)過的景點(diǎn)*/ /*自定義函數(shù)原型說明*/ void introduce();int shortestdistance();void floyed(); void display(int i,int j); void main(){/*主函數(shù)*/ int i,j; char k; for(i=0;i<=n;i++) for(j=0;j<=n;j++) cost[i][j]=INT_MAX; cost[1][3]=cost[3][1]=2; cost[2][3]=cost[3][2]=1; cost[2][4]=cost[4][2]=2;cost[3][10]=cost[10][3]=4;cost[1][10]=cost[10][1]=4;cost[2][10]=cost[10][2]=4;cost[4][10]=cost[10][4]=4; cost[1][4]=cost[4][1]=5;cost[4][5]=cost[5][4]=3;cost[4][9]=cost[9][4]=4;cost[5][9]=cost[9][5]=8;cost[5][7]=cost[7][5]=4; cost[5][6]=cost[6][5]=2; 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 cost[6][7]=cost[7][6]=1; cost[7][8]=cost[8][7]=3; cost[8][6]=cost[6][8]=4; cost[1][1]=cost[2][2]=cost[3][3]=cost[4][4]=cost[5][5]=0; cost[6][6]=cost[7][7]=cost[8][8]=cost[9][9]=cost[10][10]=0; while(1) { printf(“----------------歡迎使用中北大學(xué)導(dǎo)游系統(tǒng)!----------------n”); printf(“1.景點(diǎn)信息查詢???請按 i(introduc)鍵n”); printf(“2.景點(diǎn)最短路徑查詢?請按 s(shortestdistance)鍵n”); printf(“3.退出系統(tǒng)?????請按 e(exit)鍵n”); printf(“學(xué)校景點(diǎn)列表:n”); printf(“1:學(xué)校南門 ”); printf(“2:學(xué)生公寓 ”); printf(“3:柏林園 ”); printf(“4:餐廳 ”); printf(“5:體育館n”); printf(“6:圖書館 ”); printf(“7:重點(diǎn)實(shí)驗(yàn)室 ”); printf(“8:主樓 ”); printf(“9:科藝苑 ”); printf(“10:國防生公寓n”); printf(“請選擇服務(wù):”); scanf(“n%c”,&k); switch(k) { case 'i': printf(“進(jìn)入景點(diǎn)信息查詢:”); introduce(); break; case 's': printf(“進(jìn)入最短路徑查詢:”); shortestdistance(); break; case 'e': exit(0); default: printf(“輸入信息錯誤!n請輸入字母i或s或e.n”); break; } } }/*main*/ 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 void introduce(){/*景點(diǎn)介紹*/ int a; printf(“您想查詢哪個景點(diǎn)的詳細(xì)信息?請輸入景點(diǎn)編號:”); scanf(“%d”,&a); getchar(); printf(“n”); switch(a) { case 1: printf(“1:學(xué)校南門nn 學(xué)校的正門,前面豎立著一尊彭德華的石像,氣勢宏偉。nn”);break; case 2: printf(“2:學(xué)生公寓集中的地方。nn”);break; case 3: printf(“3:柏林園nn 晨讀鍛煉得地方。nn”);break; case 4: printf(“4:餐廳nn 學(xué)生老師就餐的地方nn”);break; case 5: printf(“5:體育館nn 體育館nn 學(xué)生上體育課及運(yùn)動的場地,設(shè)有田徑場、足球場、籃球場等。nn”);break; case 6: printf(“6:圖書館nn 學(xué)校信息資源中心,內(nèi)設(shè)大量的自習(xí)室。nn”);break; case 7: printf(“7:重點(diǎn)實(shí)驗(yàn)室nn 我校的研究科研中心nn”);break; case 8: printf(“8:主樓nn 學(xué)校行政辦公的主樓。nn”);break; case 9: printf(“9:科藝苑nn 有咖啡廳和放映室。nnn”);break; case 10: printf(“10: 國防生公寓nn 國防生居住地地方。nn”);break; default: printf(“景點(diǎn)編號輸入錯誤!請輸入1->10的數(shù)字編號!nn”);break; } }/*introduce*/ int shortestdistance(){/*要查找的兩景點(diǎn)的最短距離*/ int i,j; printf(“請輸入要查詢的兩個景點(diǎn)的編號(1->10的數(shù)字編號并用','間隔):”); 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 scanf(“%d,%d”,&i,&j); if(i>n||i<=0||j>n||j<0) { printf(“輸入信息錯誤!nn”); printf(“ 請輸入要查詢的兩個景點(diǎn)的編號(1->10的數(shù)字編號并用','間隔):n”); scanf(“%d,%d”,&i,&j); } else { floyed(); display(i,j); } return 1;}/*shortestdistance*/ void floyed(){/*用floyed算法求兩個景點(diǎn)的最短路徑*/ int i,j,k; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { shortest[i][j]=cost[i][j]; path[i][j]=0; } for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(shortest[i][j]>(shortest[i][k]+shortest[k][j])) {/*用path[][]記錄從i到j(luò)的最短路徑上點(diǎn)j的前驅(qū)景點(diǎn)的序號*/ shortest[i][j]=shortest[i][k]+shortest[k][j]; path[i][j]=k; path[j][i]=k; } }/*floyed*/ void display(int i,int j){/* 打印兩個景點(diǎn)的路徑及最短距離 */ int a,b; a=i; b=j; 共 頁 第 頁 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 裝 ┊ ┊ ┊ ┊ ┊ 訂 ┊ ┊ ┊ ┊ ┊ 線 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ 長 春 大 學(xué) 課程設(shè)計(jì)紙 printf(“您要查詢的兩景點(diǎn)間最短路徑是:nn”); if(shortest[i][j]!=INT_MAX) { if(i { printf(“%d”,b); while(path[i][j]!=0) {/* 把i到j(luò)的路徑上所有經(jīng)過的景點(diǎn)按逆序打印出來*/ printf(“<-%d”,path[i][j]); if(i j=path[i][j]; else i=path[j][i]; } printf(“<-%d”,a); printf(“nn”); printf(“(%d->%d)最短距離是:%d米nn”,a,b,shortest[a][b]); } else { printf(“%d”,a); while(path[i][j]!=0) {/* 把i到j(luò)的路徑上所有經(jīng)過的景點(diǎn)按順序打印出來*/ printf(“->%d”,path[i][j]); if(i j=path[i][j]; else i=path[j][i]; } printf(“->%d”,b); printf(“nn”); printf(“(%d->%d)最短距離是:%5d米nn”,a,b,shortest[a][b]); } } else printf(“輸入錯誤!不存在此路!nn”); printf(“n”);}/*display*/ 共 頁 第 頁 數(shù)據(jù)庫課程設(shè)計(jì) —全國鐵路咨詢系統(tǒng) 目錄 一.需求分析****************************************** 3 二.概要設(shè)計(jì)****************************************** 三.儲存結(jié)構(gòu)設(shè)計(jì)************************************** 四.詳細(xì)設(shè)計(jì)****************************************** 五.用戶手冊****************************************** 六.測試數(shù)據(jù)****************************************** 七.心得體會****************************************** 8 11 17 18 26 一、需求分析 1、問題描述 由于不同目的的旅客對交通工具有不同的要求。例如,因公出差的旅客希望在旅途中 的時間盡可能短,出門旅游的游客則期望旅費(fèi)盡可能省。編制一個全國城市間的交通咨詢程 序,為旅客提供兩種最優(yōu)決策的交通咨詢。 根據(jù)鐵路的特征,數(shù)據(jù)的儲存需要使用圖的結(jié)構(gòu)。每個城市之間有不同的車次,每個車次的始發(fā)站、路過車站和終點(diǎn)站都不一樣,所以兩個城市之間就有指向明確的邊,是一個有向圖;而由于車次的不一樣,所以發(fā)車時間,到站時間,價(jià)格等也會不一樣;所以每兩個點(diǎn)之間不止兩條邊,可能存在不同的多條邊。 2、功能需求 鐵路咨詢的對象是用戶,所以,需要一個對用戶友好的功能菜單,根據(jù)用戶可能需要的實(shí)際需求,功能菜單中可能會包括以下要點(diǎn): 1:顯示所有車站信息 2: 顯示所有車次信息(包括時刻表) 3: 查詢車站信息 4: 查詢兩個城市之間的鐵路信息 5: 增加或刪除車站 6: 增加或刪除鐵路信息 7: 增加、刪除或修改時刻表、距離和價(jià)格 8:尋找兩城市間最省錢的一條路徑 9:尋找兩城市間最省時間的一條路徑 10:尋找兩城市間所有路徑(按費(fèi)用從低到高排序輸出) 11:尋找兩城市間所有路徑(按所用時間從少到多排序輸出) 12:退出咨詢系統(tǒng) 圖的初始數(shù)據(jù)從文本中讀入,文本是老師給的標(biāo)準(zhǔn)數(shù)據(jù)。 3、輸入及輸出格式 (1):輸入格式: A:圖的初始數(shù)據(jù)輸入 數(shù)據(jù)的初始化是需要從文本中讀入的,所以不需要有專門的文本輸入函數(shù),只需要給出讀文本的函數(shù)input();使用input()函數(shù)從測試數(shù)據(jù)的三個文本中讀入數(shù)據(jù),然后使用創(chuàng)建圖的函數(shù)CreateGraph()創(chuàng)建起整個圖。初始數(shù)據(jù)的讀入,分別是從station.txt中讀入每個城市站點(diǎn)的名稱的城市編號,從iinformation.txt中讀入每個城市間的鐵路信息,從railway.txt中讀入所有鐵路線的信息。 如: 以下從station.txt中節(jié)選部分 0 北京廣州石家莊鄭州武漢長沙 以下從information.txt中節(jié)選部分 出發(fā)城市編號 到達(dá)城市編號 車次 里程 費(fèi)用 出發(fā)時刻 到達(dá)時刻 0 1000 287 62.5 0000 0246 0 1016 287 0060 0275 0 1001 137 23.5 0000 0117 0 1017 137 28.5 0060 0163 0 1002 1199 156.5 0000 1028 1008 1257 162.5 0000 1077 以下從railway.txt中節(jié)選部分 各條鐵路線上城市編號(此行可去掉) 京廣線 0 2 3 4 5 6 1 京九線 0 13 14 12 京滬線 0 8 9 10 11 7 隴海線 18 10 3 20 24 19 B:用戶要求輸入 用戶在使用本程序時,會要求用戶輸入各種數(shù)據(jù),如城市編號id、抉擇選項(xiàng)y/n等;用戶只需要按照程序菜單的要求輸入即可。如城市編號id就是初始化數(shù)據(jù)(文本數(shù)據(jù))中每個城市就有的編號,用戶在不知道城市編號之前先查看一下城市信息就可以清楚明了的知道城市id了。 (2):輸出格式 在系統(tǒng)的管理下,為了用戶的查詢方便,需要有多重輸出方式。如每條鐵路線上信息的輸出。這里面就包括了,在每條鐵路上所有車次信息,每個車次始發(fā)站信息、過站信息和終點(diǎn)站信息。 樣例如下: 蘭新線中有以下車次: 1005次列車運(yùn)行情況: 出發(fā)城市 到達(dá)城市 車次 距離(km)出發(fā)時間 到達(dá)時間 費(fèi)用(元) 蘭州 酒泉 1005 748 0:0 10:41 酒泉 烏魯木齊 1005 797 10:51 22:14 152.5 烏魯木齊 阿拉山口 1005 477 22:24 5:13 64.5 1013次列車運(yùn)行情況: 出發(fā)城市 到達(dá)城市 車次 距離(km)出發(fā)時間 到達(dá)時間 費(fèi)用(元) 阿拉山口 烏魯木齊 1013 477 0: 0 6:49 64.5 烏魯木齊 酒泉 1013 797 6:59 18:22 152.5 酒泉 蘭州 1013 748 18:32 5:13 對于每個城市信息的輸出,只需要輸出經(jīng)過每個城市的鐵路新路即可,當(dāng)然必須得輸出城市站點(diǎn)的id,方便用戶的查詢和管理 樣例如下: 城市編號 城市名稱 過站鐵路線 0 北京 京廣線 京九線 京滬線 廣州 京廣線 石家莊 京廣線 鄭州 京廣線 隴海線 武漢 京廣線 長沙 京廣線 株洲 京廣線 滬昆線 上海 京滬線 滬昆線 二、概要設(shè)計(jì) 1.數(shù)據(jù)特性分析 (1):整體結(jié)構(gòu)分析 鐵路交通咨詢模擬系統(tǒng)管理的是全國的各個城市間的鐵路信息。對于整體的全 國鐵路信息來說,每一個城市站點(diǎn)就是一個頂點(diǎn)節(jié)點(diǎn),城市與城市之間的每一個車 次信息就是一條有向邊。所有整個咨詢系統(tǒng)應(yīng)該是一個有向圖結(jié)構(gòu)。從A城市出發(fā) 到B城市,可能會有多個車次。 如下例: 出發(fā)城市 到達(dá)城市 車次 距離(km)出發(fā)時間 到達(dá)時間 費(fèi)用(元) 北京 石家莊 1000 287 0: 0 4: 6 62.5 北京 石家莊 1016 287 1: 0 4:35 所以每兩個城市頂點(diǎn)之間就可能會有多條有向邊,所以這個圖也不會是 一個有 向簡單圖了。為了城市節(jié)點(diǎn)能夠動態(tài)的擴(kuò)充和刪除不受影響,我對于頂點(diǎn)的儲存采 用鏈表結(jié)構(gòu)不使用順序表結(jié)構(gòu),定義一個頂點(diǎn)鏈表類VertexList。這樣,雖然鏈表查 詢和其節(jié)點(diǎn)的刪除的時間復(fù)雜度受到了一定的影響,但這樣設(shè)計(jì)出來的鐵路網(wǎng)圖才 更具有一般性個實(shí)用性。對于查找的時間復(fù)雜度問題的解決,我在后面也會給出方案。 (2):城市頂點(diǎn)分析 對于每一城市來說,在全國的鐵路網(wǎng)中,它就是一個火車站節(jié)點(diǎn)。每一個火車,它都應(yīng)該會有自己的名字,過站的鐵路線等。為了咨詢系統(tǒng)管理和維護(hù)的方便,在 文本數(shù)據(jù)中,我們就人為的給每一個城市都編上序號id,每一個不同id對應(yīng)了一 個不同的城市節(jié)點(diǎn)。由于每個城市的id都是唯一的,所以在頂點(diǎn)的鏈表結(jié)構(gòu)里面,完全可以定義一個哈希表haxi[n],對于haxi[i]來說,它存儲的就是id為i的城市 在內(nèi)存中地址。這樣,頂點(diǎn)鏈表在哈希表的支持下,就能完美解決查找、添加、刪除的時間復(fù)雜度問題了。 在整個鐵路網(wǎng)中,每一個城市就是頂點(diǎn),每一個頂點(diǎn),就是應(yīng)該有一個邊鏈表 用于儲存此城市能到達(dá)所有城市的各個不同車次的信息,也就是各個不同的邊。如: 出發(fā)城市編號 到達(dá)城市編號 車次 里程 費(fèi)用 出發(fā)時刻 到達(dá)時刻 0 1000 287 62.5 0000 0246 0 1016 287 0060 0275 從上例我們可以看出,對于每個頂點(diǎn)的不同邊來說,每一個不同的邊就有一個獨(dú)有 的車次。所以這樣,對于邊的儲存,我們也可以采用哈希表結(jié)構(gòu)。經(jīng)觀察發(fā)現(xiàn),每 一車次都大于1000,所以,哈希表的id=車次-1000;對于編號為a的城市節(jié)點(diǎn)haxi[k] 來說,它儲存的是為城市a中車次為:1000+k的一條邊,邊里面就有到達(dá)城市、出發(fā)和到達(dá)時間、費(fèi)用、距離等等。 (3):邊數(shù)據(jù)分析 對于圖來講,邊就是一個邏輯結(jié)構(gòu),溝通頂點(diǎn)與頂點(diǎn)之間的關(guān)系。同時了,邊還有其物理特性。他需要儲存邊的權(quán)值等,它需要開辟儲存空間來存儲數(shù) 據(jù)。在鐵路網(wǎng)中,每兩個城市之間不同的車次信息就是一條不同的邊,所以,我需要把物理特性給單獨(dú)列出來,成為一個類LineInformation,用于表示邊 的物理信息。對于圖中抽象的邊,也需要定義一個類EdgeNode,用于溝通 圖中原本孤立的頂點(diǎn),使之變成一個完整的圖 2.整體概要設(shè)計(jì) 前面,我提到了有頂點(diǎn)類station、頂點(diǎn)鏈表類VertexList、邊的物理類LineInformation和邊的邏輯類EdgeNode、火車線路類railway;對于整個完整的圖類來說,還有兩個主要的類沒有提及,那就是圖類RailwayNet和管理圖類的類management。當(dāng)然對于圖中需要完成各個不同功能的時候,我還寫了許多的輔助類。如查找兩個車站之間所有路徑時需要用到的LinStack,當(dāng)然還有LinStack的類的基石StackNode類。整個咨詢系統(tǒng)還有許多的結(jié)構(gòu)體,這些結(jié)構(gòu)體的功能我就不一一敘述了,詳細(xì)可見源代碼的注釋。下面我就列出各個類的關(guān)系圖 三.儲存結(jié)構(gòu)設(shè)計(jì) 1、存儲結(jié)構(gòu)的確定 數(shù)據(jù)結(jié)構(gòu)的目的是有效組織和處理數(shù)據(jù)。為了有效組織和處理數(shù)據(jù),先要分析多項(xiàng)式操作的特點(diǎn)和指針?biāo)伎臻g比例,然后確定最優(yōu)的存儲結(jié)構(gòu)。 1.鐵路網(wǎng)是由鐵路和火車站構(gòu)成,每個火車站相當(dāng)于一個定點(diǎn),每新建一條鐵路就相當(dāng)于新建定點(diǎn)之間的邊 2.車站之間可以任意到達(dá),可直接相連,也可以間接相連,且怎么連接是不固定的。3.綜上所述,資源管理器的存儲結(jié)構(gòu)采用樹形結(jié)構(gòu)。 2、類的結(jié)構(gòu)設(shè)計(jì)圖: management類圖: RailWay類圖: VertexList類圖: RailWay類圖: LineInformation類圖: EdgeNode結(jié)構(gòu)圖: Station類圖; 四、詳細(xì)設(shè)計(jì) 1.管理類management class management{ private: vector void NextDisplay(EdgeNode* edge, LinStack //私有的函數(shù),以深度優(yōu)先遍歷的方式尋找兩點(diǎn)之間的所有路徑 void DepthFirstSearchPath(vector //私有函數(shù),以Dijkastra算法尋找最節(jié)省時間的路徑 void ShortestCost(vector void QuickSort(vector }; VertexList & Vertex(){ return vertex;} vector void InsertVertex(station* s);//在頂點(diǎn)v1和v2之間插入一條邊(邊的起點(diǎn)為v1,終點(diǎn)為v2)void InsertEdge(int v1, int v2, EdgeNode* & ed);//刪除編號為id的城市頂點(diǎn) void DeleteVertex(int id);//刪除邊edge void DeleteEdge(int v1, int v2);//創(chuàng)建一個鄰接表圖 void CreateGraph(RailwayNet & graph, vector void display(RailwayNet & graph);//返回頂點(diǎn)v1和v2的第一條邊 EdgeNode* const GetFirstEdge(int v1, int v2);//獲取起點(diǎn)origin到終點(diǎn)terminal的最少費(fèi)用 float GetShortestCost(int origin, int terminal, LineInformation & edge);//獲取邊路徑path中的用時 int GetPathTime(vector float GetPathCost(vector void GetAllPath(vector //頂點(diǎn)鏈表類 class VertexList{ private: station *head;//頭指針 int size;//鏈表的大?。ㄔ氐膫€數(shù)) station* haxi[1000];//哈希表,內(nèi)存有節(jié)點(diǎn)的地址(哈希表中的下標(biāo)與對應(yīng)城市節(jié)點(diǎn)的ID相等)public: };VertexList();~VertexList();station* & GetHead(){ return head;} int & GetSize(){ return size;} //按照id從小到大的順序?qū)ity插入鏈表中 void insert(station* city);//刪除城市編號為id的節(jié)點(diǎn) void Delete(int id);//根據(jù)城市的id獲取城市節(jié)點(diǎn) station* GetVertex(int id);station** GetVertexHaxi(){ return haxi;} int IsVertexExist(int id); 4.頂點(diǎn)類 class station{ private: int m_size;//邊鏈表的大小 EdgeNode* haxi[100];//以此車站為始發(fā)站的邊的哈希表(下標(biāo)為:車次-1000)vector station(string na, int i);//構(gòu)造函數(shù) station(const station & sta);//復(fù)制構(gòu)造函數(shù) void Delete();//刪除函數(shù) //接口函數(shù) station* prior;//指向上一個車站 station *next;//指向下一個車站 EdgeNode *head;//指向第一條邊節(jié)點(diǎn) string m_name;int m_id;vector };string & GetName(){ return m_name;} int & GetId(){ return m_id;} vector LineInformation information;EdgeNode *next;//下一個邊結(jié)點(diǎn) EdgeNode *prior;//上一個邊節(jié)點(diǎn) }; 6.邊物理類LineInformation class LineInformation{ private: int m_DepartId;//出發(fā)城市編號 int m_ArriveId;//到達(dá)城市編號 int m_TrainNumber;//車次 int m_distance;//車程 float m_cost;//費(fèi)用 int m_DepartTime;//出發(fā)時間 int m_ArriveTime;//到達(dá)時間 //默認(rèn)構(gòu)造函數(shù) int DepartId=0, int ArriveId=0,LineInformation(int DepartId = 0, int ArriveId = 0, int Train = 0, int distance =-1, //復(fù)制構(gòu)造函數(shù) LineInformation(const LineInformation & l);~LineInformation(){};LineInformation operator=(const LineInformation& e);//接口函數(shù) int & GetDepartTime(){ return m_DepartTime;} int & GetArriveTime(){ return m_ArriveTime;} int & GetTrainNumber(){ return m_TrainNumber;} public: float cost = 0, int DepartTime =-1, int ArriveTime =-1); };int & GetDepartId(){ return m_DepartId;} int & GetArriveId(){ return m_ArriveId;} int & GetDistance(){ return m_distance;} float & GetCost(){ return m_cost;} 7.火車線路類railway class railway{ private: };string m_name;//火車線名 vector 8.自定義棧類 template }; template //定義類LinStack //數(shù)據(jù)元素 private: StackNode //指針 //前視定義,否則友元無法定義 //模板類型為T public: //構(gòu)造函數(shù)1,用于構(gòu)造頭結(jié)點(diǎn) StackNode(StackNode StackNode(const T& item, StackNode };StackNode //頭指針 //數(shù)據(jù)元素個數(shù) //構(gòu)造函數(shù) public: LinStack(void);~LinStack(void);T Pop(void); //析構(gòu)函數(shù) //入棧 //出棧 //取棧頂元素 //堆棧非空否 void Push(const T& item);T GetTop(void)const; int NotEmpty(void)const; bool IsInStack(T a);//判斷元素a是否在棧中 void Empty();//清空棧 int GetSize();//獲取棧中元素的個數(shù) void display();//輸出棧中元素 五、用戶手冊 1.本程序運(yùn)行在Windows操作系統(tǒng)下,VS2013,按F7編譯,F(xiàn)5運(yùn)行。 2.在程序運(yùn)行前有預(yù)設(shè)函數(shù),最好選擇預(yù)設(shè)函數(shù),然后進(jìn)行測試。 3.在菜單中選擇你想進(jìn)的功能,然后輸入前面的數(shù)字即可。 用戶菜單如下: *****************************全國鐵路交通咨詢模擬**************************** 1: 顯示所有車站信息 2: 顯示所有車次信息(包括時刻表) 3: 查詢車站信息“ 4: 查詢兩個城市之間的鐵路信息 5: 增加或刪除車站 6: 增加或刪除鐵路信息 7: 增加、刪除或修改時刻表、距離和價(jià)格 8: 尋找兩城市間最省錢的一條路徑 9: 尋找兩城市間最省時間的一條路徑 10:尋找兩城市間所有路徑(按費(fèi)用從低到高排序輸出) 11:尋找兩城市間所有路徑(按所用時間從少到多排序輸出) 12: 退出咨詢系統(tǒng)” *****************************************************************************" 六、測試數(shù)據(jù) 1.用戶菜單 在輸入指令一欄輸入你想要使用的功能的數(shù)字編號。如:輸入1 功能為:顯示所有車站信息 由于數(shù)據(jù)過多,這里只截取部分輸出 輸入指令:2 功能:查詢所有車次信息 數(shù)據(jù)量太大,也只截取部分輸出。 輸入指令:3 功能:查詢車站信息 車站信息有: 1.從此車站出發(fā)各個車次信息。2.從其他車站出發(fā)到達(dá)此車站的信息 輸入指令:4 功能:查詢兩個車站之間的信息 查詢的時候,是由先后順序的,先輸入的是出發(fā)城市,后輸入的到達(dá)城市 輸入指令:5 功能:增加或刪除車站 樣例1:增加成功 樣例2:增加失敗 錯誤原因:編號輸入錯誤 編號id為12:九龍 所以此編號已有城市占用,輸入錯誤 樣例3:刪除成功 現(xiàn)在可查詢廣州的信息 發(fā)現(xiàn)廣州此時已不存在,刪除成功 樣例4:刪除失敗 錯誤原因:id為31 的城市不存在 輸入指令:6 功能:增加或刪除鐵路信息 樣例1:增加失敗 失敗原因:id為1的城市已刪除,不能再城市1余城市6之間增加鐵路 樣例2:增加成功 此時新建鐵路狀態(tài):還有鐵路線,沒有車次 注:想要鐵路線有火車運(yùn)行,必須補(bǔ)充車次信息 樣例3:刪除成功 樣例4:刪除失敗 失敗原因:不存在從城市9到城市13的鐵路 輸入指令:7 功能:增加、刪除或修改時刻表、距離和價(jià)格 測試樣例: 可查詢修改后的價(jià)格 出發(fā)城市:6 株洲 到達(dá)城市:5 長沙 車次為:1022的信息中 價(jià)格:999 修改成功! 輸入指令:8 功能:尋找兩城市間最省錢的路勁 輸入指令:9 功能:尋找兩城市間最省時間的路勁 輸入指令:10 功能:尋找兩城市間所有路徑(按費(fèi)用從低到高排序輸出) 數(shù)據(jù)過多,取前二十條顯示,我也只截取前一部分?jǐn)?shù)據(jù) 輸入指令:11 功能:尋找兩城市間所有路徑(按所用時間從少到多排序輸出) 數(shù)據(jù)過多,取前二十條顯示,我也只截取前一部分?jǐn)?shù)據(jù) 注:后面的測試時前面面修改后的結(jié)果,所以,計(jì)算的結(jié)果和初始化數(shù)據(jù)計(jì)算的結(jié)果可能會不一致,這是因?yàn)橹皇强赡苡?jì)算會用到我修改后的數(shù)據(jù),所以存在不一致的問題。 七、心得體會第二篇:校園導(dǎo)游實(shí)驗(yàn)報(bào)告——數(shù)據(jù)結(jié)構(gòu)
第三篇:校園導(dǎo)航系統(tǒng)數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)
第四篇:課程設(shè)計(jì)(校園導(dǎo)游)
第五篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-全國鐵路交通咨詢模擬