您好,登錄后才能下訂單哦!
這篇文章主要介紹了如何使用C語(yǔ)言實(shí)現(xiàn)校園導(dǎo)游系統(tǒng),具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
中國(guó)地大物博,文化底蘊(yùn)頗深,旅游資源更是豐富多彩,也越來(lái)越流行“大學(xué)打卡熱”,中國(guó)很多大學(xué)校園成為了游客們的打卡的“景區(qū)”,為了給來(lái)訪西安郵電大學(xué)的游客更加方便、快捷的提供服務(wù)信息,以及為在校學(xué)生提供合適的行走路線,因此開發(fā)“西安郵電大學(xué)校園導(dǎo)航系統(tǒng)”給游客以及在校學(xué)生提供更好的服務(wù)。
本次課程設(shè)計(jì)的主題為校園導(dǎo)航系統(tǒng),主要目的是使學(xué)生學(xué)習(xí)的理論知識(shí)與實(shí)際應(yīng)用相結(jié)合,避免學(xué)生在“紙上談兵”。親歷實(shí)際應(yīng)用的設(shè)計(jì)過(guò)程,培養(yǎng)學(xué)生獨(dú)立思考、處理具體問(wèn)題的能力。理論是單一的,但實(shí)際應(yīng)用問(wèn)題是多變的,甚至是與理論相沖突的,如何滿足實(shí)際問(wèn)題的需求,處理好理論與應(yīng)用的沖突,是每個(gè)學(xué)生都應(yīng)該學(xué)會(huì)的。
對(duì)于“校園導(dǎo)航系統(tǒng)”的開發(fā)者,即學(xué)生本人來(lái)說(shuō),對(duì)其能力的提高主要分以下幾點(diǎn):
① 深化其腦海中對(duì)“圖”這種數(shù)據(jù)的邏輯結(jié)構(gòu)的認(rèn)知;
② 要求學(xué)生熟練掌握“圖”的鄰接矩陣創(chuàng)建、鄰接表創(chuàng)建;
③ 獨(dú)立編寫代碼,提高學(xué)生邏輯思維能力;
④ 懂得運(yùn)用幾種最基本的“圖”操作的算法。
本系統(tǒng)功能全部劃分給管理方和游客兩種人群。
①游客權(quán)限有:顯示地圖基本信息、查詢某個(gè)地點(diǎn)的交通路線基本情況、查詢兩兩地之間中轉(zhuǎn)最少的路徑、簡(jiǎn)單路徑、最短路徑等。
②管理方登錄后,除了使用用戶的所有權(quán)限之外,還可以行使地圖系統(tǒng)的高級(jí)權(quán)限,有:添加新頂點(diǎn)、添加新路線、撤銷舊路線等。
下圖為校園導(dǎo)航系統(tǒng)的平面圖:
1)增加新地點(diǎn)
①輸入要增加的地點(diǎn)名稱和地點(diǎn)信息,并且圖的頂點(diǎn)數(shù)加1;
②修改flag文件中圖的頂點(diǎn)數(shù);
③可在introduce文件中查看新地點(diǎn)是否增加成功;
④實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員增加新地點(diǎn)的功能。
2)增加新路線
①輸入要增加路線的起始地點(diǎn)、終止地點(diǎn)和路徑的距離并且圖的邊數(shù)加1;
②修改flag文件中圖的邊數(shù);
③可在adj文件中查看新路線是否增加成功;
④實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員增加新路線的功能。
3)撤銷舊路線
①輸入要撤銷路線的起始地點(diǎn)和終止地點(diǎn),并讓其路徑值為無(wú)窮,圖的邊數(shù)減1;
②修改flag文件中圖的邊數(shù);
③可在adj文件中查看舊路線是否撤銷成功;
④實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員撤銷舊路線的功能。
4)校園平面圖
①將校園平面圖保存在map文件中;
②調(diào)用打印地圖函數(shù);
③實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員和游客對(duì)校園平面圖的查看。
5)地點(diǎn)信息查詢
①分三種查詢方式:地點(diǎn)編號(hào)查詢、地點(diǎn)名稱查詢、地點(diǎn)編號(hào)名稱共同查詢;
②當(dāng)選擇地點(diǎn)編號(hào)查詢的時(shí)候,先打印出各地點(diǎn)名稱對(duì)應(yīng)的編號(hào),然后輸入要查詢的地點(diǎn)的編號(hào),即可顯示出所查地點(diǎn)的信息;
③當(dāng)選擇地點(diǎn)名稱查詢的時(shí)候,輸入需要查詢的地點(diǎn)名稱,如果有所要查詢的地點(diǎn)名稱 時(shí),將顯示出所查地點(diǎn)的信息;
④當(dāng)選擇地點(diǎn)編號(hào)名稱共通查詢的時(shí)候,先打印出各地點(diǎn)名稱對(duì)應(yīng)的編號(hào),然后輸入要查詢的地點(diǎn)的編號(hào)和地點(diǎn)名稱,即可顯示出所要查詢的地點(diǎn)的信息;
⑤實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員和游客對(duì)地點(diǎn)信息的查詢。
6)問(wèn)路查詢
①分三種路線查詢方式:兩個(gè)地點(diǎn)之間所有的簡(jiǎn)單路徑、兩個(gè)地點(diǎn)之間中轉(zhuǎn)最少的路徑、兩個(gè)地點(diǎn)之間最短路徑;
②當(dāng)查詢兩個(gè)地點(diǎn)之間所有的簡(jiǎn)單路徑時(shí),可以采用深度優(yōu)先遍歷,將所有路線打印出來(lái);
③當(dāng)查詢兩個(gè)地點(diǎn)之間中轉(zhuǎn)最少的路徑時(shí),可以采用廣度優(yōu)先遍歷,類似于樹的按層次遍歷,當(dāng)起點(diǎn)遇到終點(diǎn)時(shí),即為中轉(zhuǎn)最少的路徑,也可以采用深度優(yōu)先遍歷,記錄中轉(zhuǎn)的地點(diǎn)最少的那條路徑輸出;
④當(dāng)查詢兩個(gè)地點(diǎn)之間的最短路徑時(shí),可以采用Dijkstra算法,借助兩個(gè)輔助數(shù)組dist和path來(lái)查詢最短路徑;
⑤實(shí)現(xiàn)了校園導(dǎo)航系統(tǒng)管理員和游客對(duì)路線的查詢。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #define MAXSIZE 66 //數(shù)組長(zhǎng)度的最大值 #define MAXVEX 20 //最大頂點(diǎn)個(gè)數(shù) #define INFINITY 32767 //表示極大值 //以下全局變量用于DFS中 int count1 = 0;// DFSALL ,路徑計(jì)數(shù)器,全局變量,直接++,如果局部變量,遞歸到上一層值還是沒變 int way1[MAXSIZE] = {0}; //路徑數(shù)組 int count2 = 0;// DFSALL ,層數(shù) int way2[MAXSIZE] = {0}; //路徑數(shù)組 int minc = MAXVEX; //中轉(zhuǎn)最少頂點(diǎn)數(shù)最值 int minway[MAXSIZE] = {0};//路徑數(shù)組 //頂點(diǎn)類型的定義 typedef struct{ char name[19]; //地點(diǎn)的名稱 char info[66]; //地點(diǎn)的介紹 int visited; //訪問(wèn)標(biāo)志 }Vextype; //鄰接矩陣的數(shù)據(jù)類型 typedef struct{ int arcs[MAXVEX][MAXVEX]; //邊(或弧)信息 Vextype vex[MAXVEX]; //頂點(diǎn)信息,頂點(diǎn)類型根據(jù)實(shí)際情況自行定義 int vexnum; //頂點(diǎn)數(shù)目 int arcnum; //邊(或弧)數(shù)目 int visited[MAXVEX]; //訪問(wèn)標(biāo)志數(shù)組,標(biāo)志是否被訪問(wèn)過(guò) }AdjMatrix; //存入地圖文件 void MapFile(AdjMatrix G){ char filename[30] = "map.txt"; FILE *fp; fp = fopen(filename,"wt"); if(fp == NULL) { printf("\n不能打開!"); exit(1); } fprintf(fp,"|------------------------------------------------------------------------------------------------|\n"); fprintf(fp,"| ☆西安郵電大學(xué)校園地點(diǎn)一覽 ☆ |\n"); fprintf(fp,"|------------------------------------------------------------------------------------------------|\n"); fprintf(fp,"| |\n"); fprintf(fp,"| 西區(qū)正門 |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| | 東區(qū)正門==================逸夫樓 |\n"); fprintf(fp,"| | | | |\n"); fprintf(fp,"| |===水煮鴿子 | | |\n"); fprintf(fp,"| | | | | |\n"); fprintf(fp,"| 基礎(chǔ) | | 安美公寓 |\n"); fprintf(fp,"| 教學(xué)樓 | | | |\n"); fprintf(fp,"| | | | | |\n"); fprintf(fp,"| | | | 安悅公寓 |\n"); fprintf(fp,"| | | 東升苑 ====| |\n"); fprintf(fp,"| | | | |\n"); fprintf(fp,"| | 圖書館 | |\n"); fprintf(fp,"| 教學(xué)實(shí)驗(yàn)樓 | | |\n"); fprintf(fp,"| | |=====================================================| |\n"); fprintf(fp,"| | | ||| 西郵橋 ||| | |\n"); fprintf(fp,"| 醫(yī)務(wù)室====| |=====================================================| |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| |===體育館 |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| 旭日苑 |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| | |\n"); fprintf(fp,"| 西區(qū)宿舍樓 |\n"); fprintf(fp,"| |\n"); fprintf(fp,"|------------------------------------------------------------------------------------------------|\n"); fclose(fp); } //打印地圖 void MapOutput(){ printf("|------------------------------------------------------------------------------------------------|\n"); printf("| ☆西安郵電大學(xué)校園地點(diǎn)一覽 ☆ |\n"); printf("|------------------------------------------------------------------------------------------------|\n"); printf("| |\n"); printf("| 西區(qū)正門 |\n"); printf("| | |\n"); printf("| | |\n"); printf("| | 東區(qū)正門==================逸夫樓 |\n"); printf("| | | | |\n"); printf("| |===水煮鴿子 | | |\n"); printf("| | | | | |\n"); printf("| 基礎(chǔ) | | 安美公寓 |\n"); printf("| 教學(xué)樓 | | | |\n"); printf("| | | | | |\n"); printf("| | | | 安悅公寓 |\n"); printf("| | | 東升苑 ====| |\n"); printf("| | | | |\n"); printf("| | 圖書館 | |\n"); printf("| 教學(xué)實(shí)驗(yàn)樓 | | |\n"); printf("| | |=====================================================| |\n"); printf("| | | ||| 西郵橋 ||| | |\n"); printf("| 醫(yī)務(wù)室====| |=====================================================| |\n"); printf("| | |\n"); printf("| |===體育館 |\n"); printf("| | |\n"); printf("| | |\n"); printf("| 旭日苑 |\n"); printf("| | |\n"); printf("| | |\n"); printf("| 西區(qū)宿舍樓 |\n"); printf("| |\n"); printf("|------------------------------------------------------------------------------------------------|\n"); } //創(chuàng)建圖,信息從文件中讀取 void Create(AdjMatrix *G){ int i,j; int m,n,weight; int vexnum,arcnum; char name[19],info[66]; for(i = 1; i <= G->vexnum; i++){ //初始化visited值,剛開始都為0 G->vex[i].visited = 0; } FILE *fp1; fp1 = fopen("flag.txt","rt"); if(fp1 == NULL){ printf("\n不能打開!"); exit(1); } FILE *fp2; fp2 = fopen("introduce.txt","rt"); if(fp2 == NULL){ printf("\n不能打開!"); exit(1); } FILE *fp3; fp3 = fopen("adj.txt","rt"); if(fp3 == NULL){ printf("\n不能打開!"); exit(1); } fscanf(fp1,"%d %d",&vexnum,&arcnum); //從文件中頂點(diǎn)的個(gè)數(shù)和邊的個(gè)數(shù) G->vexnum = vexnum; G->arcnum = arcnum; for(i = 1; i <= G->vexnum; i++){ fscanf(fp2,"%s\n%s",name,info); strcpy(G->vex[i].name,name); strcpy(G->vex[i].info,info); } for(i = 1; i <= G->vexnum; i++){ for(j = 1;j <= G->vexnum; j++){ G->arcs[i][j] = INFINITY; } } for(j = 1; j <= G->arcnum; j++){ fscanf(fp3,"%6d %6d %6d",&m,&n,&weight); G->arcs[m][n] = weight; G->arcs[n][m] = weight; } fclose(fp1); fclose(fp2); fclose(fp3); } //打印地點(diǎn)列表 void PrintPlace(AdjMatrix *G){ int i; for(i = 1; i <= G->vexnum; i++ ){ printf("\t\t\t\t\t\t%d\t%s\n",i,G->vex[i].name); } } void IntroducePlace(AdjMatrix G){ int i, num,c; int flag = 1; char n[30]; while(flag == 1 ){ system( "cls" ); printf( "\t\t\t\t\t\t——————地點(diǎn)信息查詢——————\n" ); printf("\t\t\t\t\t\t請(qǐng)選擇需要查詢的方式\n"); printf("\t\t\t\t\t\t1.地點(diǎn)編號(hào)查詢\n"); printf("\t\t\t\t\t\t2.地點(diǎn)名稱查詢\n"); printf("\t\t\t\t\t\t3.地點(diǎn)編號(hào)名稱共同查詢\n"); scanf("%d",&c); if(c == 1){ system("cls"); PrintPlace(&G); printf( "\t\t\t\t\t\t請(qǐng)輸入需要查找的地點(diǎn)編號(hào):" ); scanf( "%d", &num ); if(num > 0 && num <= G.vexnum ){ printf( "\n\n"); printf( "\t\t\t編號(hào):%d\n",num); printf( "\t\t\t名稱:%s\n", G.vex[num].name ); printf( "\t\t\t簡(jiǎn)介:%s\n\n", G.vex[num].info ); } else{ printf( "\t\t\t\t\t\t信息輸入有誤!\n" ); } printf( "\n\t\t\t\t\t\t是否繼續(xù)查詢地點(diǎn)信息?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } else if(c == 2){ system("cls"); printf("\t\t\t\t\t\t請(qǐng)輸入需要查詢的地點(diǎn)名稱:"); scanf("%s",n); for(i = 1; i <= G.vexnum; i++ ){ if(strcmp(G.vex[i].name,n) == 0){ printf( "\n\n"); printf( "\t\t\t編號(hào):%d\n",i); printf( "\t\t\t名稱:%s\n", G.vex[i].name ); printf( "\t\t\t簡(jiǎn)介:%s\n\n", G.vex[i].info ); break; } } printf( "\n\t\t\t\t\t\t是否繼續(xù)查詢地點(diǎn)信息?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } else if(c == 3){ system("cls"); PrintPlace(&G); printf( "\t\t\t\t\t\t請(qǐng)輸入需要查找的地點(diǎn)編號(hào):" ); scanf( "%d", &num ); printf("\t\t\t\t\t\t請(qǐng)輸入需要查詢的地點(diǎn)名稱:"); scanf("%s",n); if(num > 0 && num <= G.vexnum && strcmp(G.vex[num].name,n) == 0){ printf( "\n\n"); printf( "\t\t\t編號(hào):%d\n",num); printf( "\t\t\t名稱:%s\n", G.vex[num].name ); printf( "\t\t\t簡(jiǎn)介:%s\n\n", G.vex[num].info ); } printf( "\n\t\t\t\t\t\t是否繼續(xù)查詢地點(diǎn)信息?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } } system("cls"); } //地點(diǎn)信息,文件 void IntroduceFile(AdjMatrix G){ int i; char filename[30] = "introduce.txt"; FILE *fp; fp = fopen(filename,"wt"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } G.vexnum = 15; strcpy(G.vex[1].name,"西區(qū)正門"); strcpy(G.vex[1].info,"西安郵電大學(xué)長(zhǎng)安校區(qū)西區(qū)的正門"); strcpy(G.vex[2].name,"西郵橋"); strcpy(G.vex[2].info,"鏈接西安郵電大學(xué)長(zhǎng)安校區(qū)西區(qū)和東區(qū)的橋梁,過(guò)馬路請(qǐng)走西游橋"); strcpy(G.vex[3].name,"東區(qū)正門"); strcpy(G.vex[3].info,"西安郵電大學(xué)長(zhǎng)安校區(qū)東區(qū)的正門"); strcpy(G.vex[4].name,"水煮鴿子"); strcpy(G.vex[4].info,"西安郵電大學(xué)長(zhǎng)安校區(qū)西區(qū)正門口,由鴿子和噴泉組成"); strcpy(G.vex[5].name,"基礎(chǔ)教學(xué)樓"); strcpy(G.vex[5].info,"西安郵電大學(xué)教學(xué)樓,有A樓和B樓,是西安郵電大學(xué)學(xué)生們上課的地方"); strcpy(G.vex[6].name,"教學(xué)實(shí)驗(yàn)樓"); strcpy(G.vex[6].info,"西安郵電大學(xué)長(zhǎng)安校區(qū)西區(qū)實(shí)驗(yàn)樓"); strcpy(G.vex[7].name,"逸夫樓"); strcpy(G.vex[7].info,"西安郵電大學(xué)教學(xué)樓,是學(xué)生們上課的地方,很容易迷路哦"); strcpy(G.vex[8].name,"圖書館"); strcpy(G.vex[8].info,"西安郵電大學(xué)圖書館,可以借閱書籍和自習(xí)"); strcpy(G.vex[9].name,"醫(yī)務(wù)室"); strcpy(G.vex[9].info,"西安郵電大學(xué)醫(yī)務(wù)室"); strcpy(G.vex[10].name,"旭日苑"); strcpy(G.vex[10].info,"西安郵電大學(xué)西區(qū)食堂"); strcpy(G.vex[11].name,"東升苑"); strcpy(G.vex[11].info,"西安郵電大學(xué)東區(qū)食堂"); strcpy(G.vex[12].name,"體育館"); strcpy(G.vex[12].info,"西安郵電大學(xué)體育館,內(nèi)有運(yùn)動(dòng)場(chǎng)地"); strcpy(G.vex[13].name,"西區(qū)宿舍"); strcpy(G.vex[13].info,"分為長(zhǎng)思公寓和長(zhǎng)智公寓"); strcpy(G.vex[14].name,"安美公寓"); strcpy(G.vex[14].info,"分為安美公寓南樓和北樓"); strcpy(G.vex[15].name,"安悅公寓"); strcpy(G.vex[15].info,"分為安悅公寓南樓和北樓"); //把信息存到文件中 for(i = 1; i <= G.vexnum; i++){ fprintf(fp,"%s\n%s\n",G.vex[i].name,G.vex[i].info); } fclose(fp); } //鄰接矩陣信息,文件 void AdjFile(AdjMatrix G){ int i,j; char filename[30] = "adj.txt"; char filename1[30] = "flag.txt"; FILE *fp; fp = fopen(filename,"wt"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } FILE *fp1; fp1 = fopen(filename1,"wt"); if(fp1 == NULL){ printf("\n不能打開!"); exit(1); } G.vexnum = 15; G.arcnum = 24; //15個(gè)頂點(diǎn),24個(gè)邊 fprintf(fp1,"%d %d\n",G.vexnum,G.arcnum); //存入文件標(biāo)記 //初始化矩陣 for(i = 0; i <= G.vexnum; i++){ for(j = 0; j <= G.vexnum; j++){ G.arcs[i][j] = INFINITY; //權(quán)值全部賦無(wú)窮大 } } //給地點(diǎn)設(shè)置權(quán)值,即需要走的路程 G.arcs[1][3] = G.arcs[3][1] = 800; G.arcs[1][4] = G.arcs[4][1] = 120; G.arcs[2][3] = G.arcs[3][2] = 300; G.arcs[2][8] = G.arcs[8][2] = 450; G.arcs[2][9] = G.arcs[9][2] = 600; G.arcs[2][11] = G.arcs[11][2] = 100; G.arcs[2][12] = G.arcs[12][2] = 500; G.arcs[3][7] = G.arcs[7][3] = 150; G.arcs[4][5] = G.arcs[5][4] = 140; G.arcs[4][8] = G.arcs[8][4] = 200; G.arcs[5][6] = G.arcs[6][5] = 111; G.arcs[5][8] = G.arcs[8][5] = 222; G.arcs[6][8] = G.arcs[8][6] = 300; G.arcs[6][9] = G.arcs[9][6] = 417; G.arcs[6][10] = G.arcs[10][6] = 360; G.arcs[6][12] = G.arcs[12][6] = 250; G.arcs[7][14] = G.arcs[14][7] = 120; G.arcs[8][12] = G.arcs[12][8] = 345; G.arcs[9][10] = G.arcs[10][9] = 404; G.arcs[10][12] = G.arcs[12][10] = 200; G.arcs[10][13] = G.arcs[13][10] = 100; G.arcs[11][15] = G.arcs[15][11] = 150; G.arcs[14][15] = G.arcs[15][14] = 50; for(i = 1; i <= G.vexnum; ++i){ for(j = 1; j <= G.vexnum; ++j){ if(G.arcs[i][j] != INFINITY && i < j){ fprintf(fp,"%10d %10d %10d\n",i,j,G.arcs[i][j]); } } } fclose(fp1); fclose(fp); } //重置訪問(wèn)數(shù)組 void ClearVisited(AdjMatrix *G) { int i; for(i = 0; i <= MAXVEX; i++){ G->vex[i].visited = 0; //全部置0 } } //深度優(yōu)先搜索遍歷 void DfsAll(AdjMatrix *G,int s,int e){ int i,j; int shuai = 0; G->vex[s].visited = 1; //置起始點(diǎn)為1 way1[count1] = s; //把起點(diǎn)的序號(hào)存在一個(gè)數(shù)組里,此時(shí)count是0 for(i = 1; i <= G->vexnum; i++){ //遍歷頂點(diǎn) if(G->arcs[s][i] != INFINITY && G->vex[i].visited == 0 && i != e){ //權(quán)值不等于無(wú)窮,而且沒有被訪問(wèn)過(guò),并且沒有回到起點(diǎn) count1++; //數(shù)組下標(biāo)遞增 way1[count1] = i; //給數(shù)組對(duì)應(yīng)的下標(biāo)附上頂點(diǎn)值 DfsAll(G,i,e); //遞歸 G->vex[i].visited = 0; //遞歸回來(lái)返回到這一層還原這一層現(xiàn)狀 count1--; shuai = 0; //結(jié)束的標(biāo)志 continue; } if(G->arcs[s][i] != INFINITY && G->vex[i].visited ==0 && i == e && shuai == 0){ //輸出 count1++; way1[count1] = e; shuai = 1; printf("\n"); printf("\t%s",G->vex[way1[0]].name); //起始點(diǎn) for(j = 1;j <= count1; j++){ printf("-->"); printf("%s",G->vex[way1[j]].name); //依次打印 } count1--; //讓全局變量count變成0,以供其它函數(shù)使用 return; } } return ; } //所有簡(jiǎn)單路徑菜單 void AllPath(AdjMatrix G,int dist[],int path[][MAXVEX]){ int s,e; int flag = 1; while(flag == 1){ system("cls"); printf( "\t\t\t\t\t\t——————所有簡(jiǎn)單路徑查詢——————\n" ); PrintPlace(&G); printf("\n\t\t\t\t\t輸入起點(diǎn)編號(hào):"); scanf("%d",&s); printf("\t\t\t\t\t輸入終點(diǎn)編號(hào):"); scanf("%d",&e); if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e){ printf( "\t\t\t\t\t\t輸入錯(cuò)誤!\n\n" ); } else{ ClearVisited(&G); //給標(biāo)志數(shù)組初始化 count1=0; printf("\n\t\t\t從%s到%s的所有簡(jiǎn)單路徑有:\n", G.vex[s].name, G.vex[e].name); DfsAll(&G,s,e); //調(diào)用函數(shù)進(jìn)行實(shí)現(xiàn)功能 } printf("\n\n\t\t\t\t\t\t是否繼續(xù)查詢所有簡(jiǎn)單路徑?\n" ); printf("\t\t\t\t\t\t1:是\n" ); printf("\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf("%d", &flag); } system("cls"); } //中轉(zhuǎn)最少 ,也可以用廣搜,頂點(diǎn)A到頂點(diǎn)B所含邊的數(shù)目最少的路線,從A出發(fā)廣度優(yōu)先遍歷,遇到頂點(diǎn)B就可以停止了 void DfsLitter(AdjMatrix *G,int start,int end){ int shuai = 0; int i,j; G->vex[start].visited = 1; way2[count2] = start; for(i = 1; i <= G->vexnum; i++){ if(G->arcs[start][i] != INFINITY && G->vex[i].visited == 0 && i != end){ count2++; way2[count2] = i; DfsLitter(G,i,end); //遞歸 G->vex[i].visited = 0; count2--; shuai = 0; continue; } //此時(shí)搜到了所有路徑 if(G->arcs[start][i] != INFINITY && G->vex[i].visited == 0 && i == end && shuai == 0){ count2++; way2[count2] = end; shuai = 1; if(count2 < minc){ //如果count2比最大頂點(diǎn)數(shù)小 minc = count2; //就賦值 for(i = 0; i <= count2; i++){ minway[i]=way2[i]; //將記錄的way2值存到minway中 } } count2--; return; } } } //中轉(zhuǎn)次數(shù)最少簡(jiǎn)單路徑 void LitterPath(AdjMatrix G){ int i,j,s,e; int flag = 1; while (flag == 1){ int i; system("cls"); printf("\t\t\t\t\t\t——————中轉(zhuǎn)次數(shù)最少路徑查詢——————\n"); PrintPlace(&G); printf("\n\t\t\t\t\t輸入起點(diǎn)編號(hào):"); scanf( "%d", &s); printf("\t\t\t\t\t輸入終點(diǎn)編號(hào):"); scanf("%d", &e); if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e) printf("\t\t\t\t\t\t輸入錯(cuò)誤!\n\n"); else{ ClearVisited(&G); minc = MAXVEX; count2 = 0; printf("\n\t\t\t從%s到%s的中轉(zhuǎn)最少簡(jiǎn)單路徑為:\n", G.vex[s].name, G.vex[e].name); DfsLitter(&G,s,e); //深搜尋找 printf("\t\t\t%5s ",G.vex[minway[0]].name); for(i = 1; i <= minc; i++){ //mic即為count2 printf("-->"); printf("%5s ",G.vex[minway[i]].name); } printf("\n\n\t\t\t\t\t\t是否繼續(xù)查詢中轉(zhuǎn)最少簡(jiǎn)單路徑?\n"); printf("\t\t\t\t\t\t1:是\n"); printf("\t\t\t\t\t\t0:返回上級(jí)菜單\n"); scanf("%d", &flag); } system( "cls" ); } } //最短路徑,dist數(shù)組記錄各條最短路徑長(zhǎng)度,path數(shù)組記錄對(duì)應(yīng)路徑上的各頂點(diǎn) ,依最短路徑遞增次序求得各條路徑 void Dijkstra(AdjMatrix *G,int s,int e,int dist[MAXVEX],int path[][MAXVEX]){ int mindist,i,j,k,t = 1; //mindist 路徑的權(quán)值(長(zhǎng)度) for(i = 1; i <= G->vexnum; i++){ //給dist數(shù)組初始化, dist[i] = G->arcs[s][i]; //將鄰接數(shù)組每一行所對(duì)應(yīng)的列的值填入dist數(shù)組中 if(G->arcs[s][i] != INFINITY){ //如果權(quán)值不等于無(wú)窮大,則說(shuō)明有路 path[i][1] = s; //將起點(diǎn)記錄,path[i]記錄從源點(diǎn)到Vi最短路徑上的各個(gè)頂點(diǎn) } } path[s][0] = 1; //置1標(biāo)志,說(shuō)明源點(diǎn)為start for(i = 2; i <= G->vexnum; i++){ //尋找各條最短路徑 mindist = INFINITY; //將最小初值設(shè)置為無(wú)窮大 for(j = 1; j <= G->vexnum; j++){//選擇最小權(quán)值的路徑 if(!path[j][0] && dist[j] < mindist){//j未加入集合S //path數(shù)組記錄某定點(diǎn)是否加到S中 k = j; //當(dāng)前起點(diǎn)到頂點(diǎn)k權(quán)值最小 mindist = dist[j]; } } if(mindist == INFINITY){ return; //不存在start到其他頂點(diǎn)的路徑 } path[k][0] = 1; // 將頂點(diǎn)k加入到集合S中,說(shuō)明該頂點(diǎn)已經(jīng)被考察 //看有沒有更小的,進(jìn)而更新修改路徑 for(j = 1;j <= G->vexnum; j++){ //修改路徑 if(!path[j][0] && G->arcs[k][j]<INFINITY && dist[k]+G->arcs[k][j] < dist[j]){ //第k行有路且未被選中過(guò)的頂點(diǎn) &&到k的最小權(quán)值+k到j(luò)的權(quán)值<當(dāng)前到j(luò)的最小權(quán)值路徑 dist[j] = dist[k]+G->arcs[k][j]; t = 1; while(path[k][t] != 0){ //記錄最新的最短路徑 path[j][t] = path[k][t]; t++; } path[j][t] = k; path[j][t+1] = 0; } } } } //打印兩點(diǎn)間的最短路徑 void DijkstraPrint(int start, int end ,AdjMatrix G,int path[][MAXVEX]){ int i = 2; int length = 0; printf( "\n\t從%s到%s的最短路徑是:", G.vex[start].name, G.vex[end].name ); printf( " %s", G.vex[start].name ); while(path[end][i]){ //記錄的路徑 printf("-->%s ",G.vex[path[end][i]].name); length += G.arcs[path[end][i-1]][path[end][i]]; i++; } printf( "-->%s", G.vex[end].name ); length += G.arcs[path[end][i-1]][end]; printf( ",長(zhǎng)度為%dM", length); printf( "\n"); } //分菜單 最短路徑 void ShortPath(AdjMatrix G,int dist[],int path[][MAXVEX]){ int i,j,s,e; int flag = 1; while (flag == 1){ system("cls"); printf("\t\t\t\t\t\t——————最短路徑查詢——————\n"); PrintPlace(&G); printf("\n\t\t\t\t\t輸入起點(diǎn)編號(hào):"); scanf("%d",&s); printf("\t\t\t\t\t輸入終點(diǎn)編號(hào):"); scanf("%d",&e); if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e){ printf("\t\t\t\t\t\t輸入錯(cuò)誤!\n\n"); } else{ ClearVisited(&G); //菜單 Dijkstra(&G,s,e,dist,path); //算法 DijkstraPrint(s,e,G,path);//打印 } printf("\n\t\t\t\t\t\t是否繼續(xù)查詢最短路徑?\n"); printf("\t\t\t\t\t\t1:是\n"); printf("\t\t\t\t\t\t0:返回上級(jí)菜單\n"); scanf("%d",&flag); } system("cls"); } //路徑二級(jí)主菜單 void SearchPath(AdjMatrix G,int dist[],int path[][MAXVEX]){ int x,flag = 1; while(flag == 1){ //二級(jí)菜單 printf("\t\t\t1. 所有簡(jiǎn)單路徑\n"); //各頂點(diǎn)均不重復(fù) printf("\t\t\t2. 最短的簡(jiǎn)單路徑(中轉(zhuǎn)最少)\n"); printf("\t\t\t3. 最佳訪問(wèn)路徑(最短路徑長(zhǎng)度)\n"); printf("\t\t\t0. 返回主菜單\n"); printf("\t\t\t請(qǐng)選擇您需要的操作:"); scanf("%d",&x); switch(x){ case 1: system("cls");AllPath(G,dist,path);break; case 2: system("cls");LitterPath(G);break; case 3: system("cls");ShortPath(G,dist,path);break; case 0: flag = 0; break; default:printf( "\t\t\t\t\t\t\t輸入信息錯(cuò)誤,請(qǐng)重新輸入!\n" ); break; } system("cls"); } } //注冊(cè)信息 void enroll(){ char a[100]; //注冊(cè)用戶名 char b[100]; //注冊(cè)密碼 char s[100]; //再次確定密碼 int len; printf("請(qǐng)輸入您的用戶名:"); scanf("%s",a); printf("請(qǐng)?jiān)O(shè)置您的密碼:"); reset: scanf("%s",b); //用到了if goto語(yǔ)句 len = strlen(b); //讀取密碼長(zhǎng)度 if(len > 9){ printf("密碼長(zhǎng)度過(guò)長(zhǎng),請(qǐng)重新設(shè)置:"); goto reset; //if goto 語(yǔ)句 } printf("請(qǐng)?jiān)俅屋斎肽O(shè)置的密碼:"); scanf("%s",s); if(strcmp(b,s) == 0){ //字符串比較函數(shù) FILE *fp; fp=fopen("register.txt","at"); //選用追加方式,可以存多個(gè)信息 if(fp == NULL){ printf("文件不存在或者請(qǐng)先注冊(cè)!"); exit(1); } fprintf(fp,"%s %s\n",a,b); //字符串寫入函數(shù)進(jìn)行寫入操作 system("cls"); printf("\n\t------注冊(cè)成功------\n"); fclose(fp); } else if(strcmp(b,s) != 0){ printf("您兩次輸入的密碼不一致,請(qǐng)重新設(shè)置密碼!\n"); goto reset; //if goto 語(yǔ)句 } } //登陸頁(yè)面 int land(){ int i = 0; //i是為了判斷密碼長(zhǎng)度 并加密 char a[10]; char b[10]; char user_name[10]; char user_passwords[10]; printf("請(qǐng)輸入您的用戶名:"); scanf("%s",user_name); printf("請(qǐng)輸入您的密碼:"); while(i < 9 && (user_passwords[i] = getch()) && user_passwords[i] != '\r'){ //如果輸入超限 或者 遇到換行符就跳出循環(huán) printf("*"); //掩飾密碼 i++; } user_passwords[i] = 0; //字符串結(jié)束標(biāo)志 '/0' FILE *fp; fp=fopen("register.txt","rt"); //又打開文件 if(fp == NULL){ printf("文件不存在!"); exit(1); } while(fscanf(fp,"%s %s",a,b) != EOF){ //讀文件判斷賬號(hào)密碼是否正確 if(strcmp(a,user_name) == 0 && strcmp(b,user_passwords) == 0){ //字符串比較函數(shù),看是否正確 system("cls"); printf("\n\t\t\t--------登陸成功--------\n"); return 0; } } if(1){ system("cls"); printf("\n信息輸入錯(cuò)誤!(請(qǐng)檢查注冊(cè)文件信息)\n"); land(); } fclose(fp); } //增加新地點(diǎn)和信息 void AddPlace(AdjMatrix *G){ int s,e; char filename[30] = "introduce.txt"; char filename1[30] = "flag.txt"; int flag = 1; char p[20]; char i[66]; while (flag == 1){ //增加地點(diǎn)的地名 //增加地點(diǎn)的介紹 printf("請(qǐng)輸入新地點(diǎn)的地名:"); scanf("%s",p); printf("請(qǐng)輸入新地點(diǎn)的簡(jiǎn)介:"); scanf("%s",i); G->vexnum += 1; //頂點(diǎn)數(shù)加1 strcpy(G->vex[G->vexnum].name,p); strcpy(G->vex[G->vexnum].info,i); FILE *fp; fp = fopen(filename,"at"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } fprintf(fp,"%s\n%s\n",G->vex[G->vexnum].name,G->vex[G->vexnum].info); fclose(fp); FILE *fp1; fp1 = fopen(filename1,"wt"); if(fp1 == NULL){ printf("\n不能打開!"); exit(1); } fprintf(fp1,"%d %d\n",G->vexnum,G->arcnum); fclose(fp1); printf("\t\t添加地點(diǎn)成功,可打開\"introduce文件\"查看!"); //轉(zhuǎn)義字符 printf( "\n\t\t\t\t\t\t是否繼續(xù)添加地點(diǎn)?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } system("cls"); } //增加新路線 void AddRoad(AdjMatrix *G){ int s,e,weight; char filename[30] = "adj.txt"; char filename1[30] = "flag.txt"; int flag = 1; while(flag == 1){ PrintPlace(G); //打印地點(diǎn)的序號(hào) printf("請(qǐng)輸入增加路線的起點(diǎn)序號(hào):"); scanf("%d",&s); printf("請(qǐng)輸入增加路線的終點(diǎn)序號(hào):"); scanf("%d",&e); printf("請(qǐng)輸入兩條路線之間的距離:"); scanf("%d",&weight); G->arcs[s][e] = G->arcs[e][s] = weight; FILE *fp; fp = fopen(filename,"at"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } fprintf(fp,"%10d %10d %10d\n",s,e,G->arcs[s][e]); fclose(fp); FILE *fp1; fp1 = fopen(filename1,"at"); if(fp1 == NULL){ printf("\n不能打開!"); exit(1); } G->arcnum += 1; //邊數(shù)+1 fprintf(fp1,"%d %d\n",G->vexnum,G->arcnum); fclose(fp1); system("cls"); printf("\t\t添加路線成功,可打開\"adj文件\"查看!"); //轉(zhuǎn)義字符 printf( "\n\t\t\t\t\t\t是否繼續(xù)添加路線?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } system("cls"); } //刪除路線 void DelRoad(AdjMatrix *G){ int s,e,weight,i,j; char filename[30] = "adj.txt"; char filename1[30] = "flag.txt"; int flag = 1; FILE *fp; fp = fopen(filename,"at"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } FILE *fp1; fp1 = fopen(filename1,"wt"); if(fp == NULL){ printf("\n不能打開!"); exit(1); } while(flag == 1){ PrintPlace(G); printf("請(qǐng)輸入撤銷路線的起點(diǎn)序號(hào):"); scanf("%d",&s); printf("請(qǐng)輸入撤銷路線的終點(diǎn)序號(hào):"); scanf("%d",&e); //遍歷adj文件,如果遍歷到s和e,那么給它的值賦予無(wú)窮大 G->arcs[s][e] = G->arcs[e][s] = INFINITY; fprintf(fp,"%10d %10d %10d\n",s,e,G->arcs[s][e]); G->arcnum -= 1; //邊數(shù)-1 fprintf(fp1,"%d %d\n",G->vexnum,G->arcnum); fclose(fp); fclose(fp1); system("cls"); printf("\t\t撤銷路線成功,可打開\"adj文件\"查看!"); //轉(zhuǎn)義字符 printf( "\n\t\t\t\t\t\t是否繼續(xù)撤銷路線?\n" ); printf( "\t\t\t\t\t\t1:是\n" ); printf( "\t\t\t\t\t\t0:返回上級(jí)菜單\n" ); scanf( "%d", &flag ); } system("cls"); } //游客 void User(){ int x; int dist[MAXVEX];// 記錄各條最短路徑長(zhǎng)度 int path[MAXVEX][MAXVEX] = {0};//記錄對(duì)應(yīng)路徑上的各頂點(diǎn) AdjMatrix G; //鄰接矩陣 Create(&G); while(1){ printf("\t\t\t1. 校園平面圖\n"); printf("\t\t\t2. 地點(diǎn)信息查詢\n"); printf("\t\t\t3. 問(wèn)路查詢\n"); printf("\t\t\t0. 退出\n"); printf("\t\t\t請(qǐng)選擇您需要的操作:"); scanf("%d",&x); switch(x){ case 1: system("cls"); MapOutput(); break; case 2: system("cls"); IntroducePlace(G); break; case 3: system("cls"); SearchPath(G,dist,path); break; case 0: printf("\n\t\t\t\t\t\t\t"); exit(0); break; default: printf("\n———————————————輸入信息錯(cuò)誤,請(qǐng)重新輸入!!!————————————————————\n"); break; } } } //管理員菜單 void OwnerMeau(AdjMatrix G){ int c; int x; int dist[MAXVEX];// 記錄各條最短路徑長(zhǎng)度 int path[MAXVEX][MAXVEX] = {0};//記錄對(duì)應(yīng)路徑上的各頂點(diǎn) while(1){ printf("\t\t\t1. 添加新地點(diǎn)\n"); printf("\t\t\t2. 添加新路線\n"); printf("\t\t\t3. 撤銷舊路線\n"); printf("\t\t\t4. 校園平面圖\n"); printf("\t\t\t5. 地點(diǎn)信息查詢\n"); printf("\t\t\t6. 問(wèn)路查詢\n"); printf("\t\t\t0. 退出\n"); printf("\t\t\t請(qǐng)選擇您需要的操作:"); scanf("%d",&c); getchar(); switch(c){ case 1: system("cls"); AddPlace(&G); break; case 2: system("cls"); AddRoad(&G); break; case 3: system("cls"); DelRoad(&G); break; case 4: system("cls"); MapOutput(); break; case 5: system("cls"); IntroducePlace(G); break; case 6: system("cls"); SearchPath(G,dist,path); break; case 0: printf("\n\t\t\t\t\t\t\t"); exit(0); default: printf("\n———————————————輸入信息錯(cuò)誤,請(qǐng)重新輸入!!!————————————————————\n"); break; } } } //管理員登錄 void Owner(){ int x; int dist[MAXVEX];// 記錄各條最短路徑長(zhǎng)度 int path[MAXVEX][MAXVEX] = {0};//記錄對(duì)應(yīng)路徑上的各頂點(diǎn) AdjMatrix G; //領(lǐng)接矩陣 MapFile(G); IntroduceFile(G); //向文件中存入介紹信息 AdjFile(G); //向文件中存入鄰接矩陣信息 Create(&G); system("cls"); printf("\t\t1.登陸\t\t\t2.注冊(cè)并登錄\n"); printf("請(qǐng)選擇序號(hào):"); while(1){ scanf("%d",&x); switch(x){ case 1: land(); OwnerMeau(G); break; case 2: enroll(); land(); OwnerMeau(G); break; default: printf( "\n———————————————輸入無(wú)效,請(qǐng)重新正確輸入!!!————————————————————\n"); break; } } } //主函數(shù) int main(){ int flag; printf("——————————————————————————————————————————————\n"); printf("\n\t\t\t歡迎使用西安郵電大學(xué)長(zhǎng)安校區(qū)導(dǎo)游系統(tǒng) !\n\n"); printf("——————————————————————————————————————————————\n"); printf("\n\n\n"); //游客or管理員 printf("\t\t1.我是游客\t\t\t2.我是管理員\n"); printf("請(qǐng)選擇序號(hào):"); while(1){ scanf("%d",&flag); switch(flag){ case 1: system("cls"); User(); break; case 2: system("cls"); Owner(); break; default: printf("\n———————————————輸入無(wú)效,請(qǐng)重新正確輸入!!!————————————————————\n"); break; } } }
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何使用C語(yǔ)言實(shí)現(xiàn)校園導(dǎo)游系統(tǒng)”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。