首頁 > 軟體

C語言實現校園導遊系統

2022-03-17 13:00:46

本文範例為大家分享了C語言實現校園導遊系統的具體程式碼,供大家參考,具體內容如下

前言

這是大二上學期剛學資料結構完成的課設專案,裡面的功能還可以進一步的完善,僅供分享、參考、記錄使用,加油!

設計目的

中國地大物博,文化底蘊頗深,旅遊資源更是豐富多彩,也越來越流行“大學打卡熱”,中國很多大學校園成為了遊客們的打卡的“景區”,為了給來訪西安郵電大學的遊客更加方便、快捷的提供服務資訊,以及為在校學生提供合適的行走路線,因此開發“西安郵電大學校園導航系統”給遊客以及在校學生提供更好的服務。
本次課程設計的主題為校園導航系統,主要目的是使學生學習的理論知識與實際應用相結合,避免學生在“紙上談兵”。親歷實際應用的設計過程,培養學生獨立思考、處理具體問題的能力。理論是單一的,但實際應用問題是多變的,甚至是與理論相沖突的,如何滿足實際問題的需求,處理好理論與應用的衝突,是每個學生都應該學會的。
對於“校園導航系統”的開發者,即學生本人來說,對其能力的提高主要分以下幾點:
① 深化其腦海中對“圖”這種資料的邏輯結構的認知;
② 要求學生熟練掌握“圖”的鄰接矩陣建立、鄰接表建立;
③ 獨立編寫程式碼,提高學生邏輯思維能力;
④ 懂得運用幾種最基本的“圖”操作的演演算法。

設計內容

本系統功能全部劃分給管理方和遊客兩種人群。

①遊客許可權有:顯示地圖基本資訊、查詢某個地點的交通路線基本情況、查詢兩兩地之間中轉最少的路徑、簡單路徑、最短路徑等。
②管理方登入後,除了使用使用者的所有許可權之外,還可以行使地圖系統的高階許可權,有:新增新頂點、新增新路線、復原舊路線等。

下圖為校園導航系統的平面圖:

功能模組圖

各功能函數描述

1)增加新地點

①輸入要增加的地點名稱和地點資訊,並且圖的頂點數加1;
②修改flag檔案中圖的頂點數;
③可在introduce檔案中檢視新地點是否增加成功;
④實現了校園導航系統管理員增加新地點的功能。

2)增加新路線

①輸入要增加路線的起始地點、終止地點和路徑的距離並且圖的邊數加1;
②修改flag檔案中圖的邊數;
③可在adj檔案中檢視新路線是否增加成功;
④實現了校園導航系統管理員增加新路線的功能。

3)復原舊路線

①輸入要復原路線的起始地點和終止地點,並讓其路徑值為無窮,圖的邊數減1;
②修改flag檔案中圖的邊數;
③可在adj檔案中檢視舊路線是否復原成功;
④實現了校園導航系統管理員復原舊路線的功能。

4)校園平面圖

①將校園平面圖儲存在map檔案中;
②呼叫列印地圖函數;
③實現了校園導航系統管理員和遊客對校園平面圖的檢視。

5)地點資訊查詢

①分三種查詢方式:地點編號查詢、地點名稱查詢、地點編號名稱共同查詢;
②當選擇地點編號查詢的時候,先列印出各地點名稱對應的編號,然後輸入要查詢的地點的編號,即可顯示出所查地點的資訊;
③當選擇地點名稱查詢的時候,輸入需要查詢的地點名稱,如果有所要查詢的地點名稱 時,將顯示出所查地點的資訊;
④當選擇地點編號名稱共通查詢的時候,先列印出各地點名稱對應的編號,然後輸入要查詢的地點的編號和地點名稱,即可顯示出所要查詢的地點的資訊;
⑤實現了校園導航系統管理員和遊客對地點資訊的查詢。

6)問路查詢

①分三種路線查詢方式:兩個地點之間所有的簡單路徑、兩個地點之間中轉最少的路徑、兩個地點之間最短路徑;
②當查詢兩個地點之間所有的簡單路徑時,可以採用深度優先遍歷,將所有路線列印出來;
③當查詢兩個地點之間中轉最少的路徑時,可以採用廣度優先遍歷,類似於樹的按層次遍歷,當起點遇到終點時,即為中轉最少的路徑,也可以採用深度優先遍歷,記錄中轉的地點最少的那條路徑輸出;
④當查詢兩個地點之間的最短路徑時,可以採用Dijkstra演演算法,藉助兩個輔助陣列dist和path來查詢最短路徑;
⑤實現了校園導航系統管理員和遊客對路線的查詢。

各功能函數之間的呼叫關係

原始碼

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

#define MAXSIZE 66              //陣列長度的最大值 
#define MAXVEX  20                 //最大頂點個數 
#define INFINITY 32767            //表示極大值                 

//以下全域性變數用於DFS中 
int count1 = 0;// DFSALL ,路徑計數器,全域性變數,直接++,如果區域性變數,遞迴到上一層值還是沒變 
int way1[MAXSIZE] = {0}; //路徑陣列 
int count2 = 0;// DFSALL ,層數 
int way2[MAXSIZE] = {0}; //路徑陣列 
int minc = MAXVEX; //中轉最少頂點數最值 
int minway[MAXSIZE] = {0};//路徑陣列 

//頂點型別的定義
typedef struct{
    char  name[19];        //地點的名稱 
    char  info[66];    //地點的介紹 
    int visited;        //存取標誌 
}Vextype;

//鄰接矩陣的資料型別 
typedef struct{
    int arcs[MAXVEX][MAXVEX]; //邊(或弧)資訊 
    Vextype vex[MAXVEX];    //頂點資訊,頂點型別根據實際情況自行定義 
    int vexnum;        //頂點數目 
    int arcnum;     //邊(或弧)數目 
    int visited[MAXVEX];   //存取標誌陣列,標誌是否被存取過 
}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,"|                                ☆西安郵電大學校園地點一覽 ☆                                   |n");
    fprintf(fp,"|------------------------------------------------------------------------------------------------|n");
    fprintf(fp,"|                                                                                                |n"); 
    fprintf(fp,"|                   西區正門                                                                     |n"); 
    fprintf(fp,"|                      |                                                                         |n");     
    fprintf(fp,"|                      |                                                                         |n");
    fprintf(fp,"|                      |                                   東區正門==================逸夫樓      |n");                          
    fprintf(fp,"|                      |                                                     |         |         |n");     
    fprintf(fp,"|            |===水煮鴿子                                                    |         |         |n"); 
    fprintf(fp,"|            |         |                                                     |         |         |n");     
    fprintf(fp,"|           基礎       |                                                     |      安美公寓     |n");    
    fprintf(fp,"|          教學樓      |                                                     |         |         |n");    
    fprintf(fp,"|            |         |                                                     |         |         |n");  
    fprintf(fp,"|            |         |                                                     |      安悅公寓     |n");  
    fprintf(fp,"|            |         |                                          東昇苑 ====|                   |n");    
    fprintf(fp,"|            |         |                                                     |                   |n");
    fprintf(fp,"|            |       圖書館                                                  |                   |n");    
    fprintf(fp,"|       教學實驗樓     |                                                     |                   |n");     
    fprintf(fp,"|            |         |=====================================================|                   |n");     
    fprintf(fp,"|            |         |                 |||   西郵橋   |||                  |                   |n");
    fprintf(fp,"|  醫務室====|         |=====================================================|                   |n");
    fprintf(fp,"|                      |                                                                         |n");    
    fprintf(fp,"|                      |===體育館                                                                |n");     
    fprintf(fp,"|                      |                                                                         |n");    
    fprintf(fp,"|                      |                                                                         |n");    
    fprintf(fp,"|                    旭日苑                                                                      |n");     
    fprintf(fp,"|                      |                                                                         |n");
    fprintf(fp,"|                      |                                                                         |n");
    fprintf(fp,"|                  西區宿舍樓                                                                       |n");      
    fprintf(fp,"|                                                                                                |n");        
    fprintf(fp,"|------------------------------------------------------------------------------------------------|n");
    fclose(fp);
}

//列印地圖
void MapOutput(){
    printf("|------------------------------------------------------------------------------------------------|n");
    printf("|                                ☆西安郵電大學校園地點一覽 ☆                                   |n");
    printf("|------------------------------------------------------------------------------------------------|n");
    printf("|                                                                                                |n"); 
    printf("|                   西區正門                                                                     |n"); 
    printf("|                      |                                                                         |n");     
    printf("|                      |                                                                         |n");
    printf("|                      |                                   東區正門==================逸夫樓      |n");                          
    printf("|                      |                                                     |         |         |n");     
    printf("|            |===水煮鴿子                                                    |         |         |n"); 
    printf("|            |         |                                                     |         |         |n");     
    printf("|           基礎       |                                                     |      安美公寓     |n");    
    printf("|          教學樓      |                                                     |         |         |n");    
    printf("|            |         |                                                     |         |         |n");  
    printf("|            |         |                                                     |      安悅公寓     |n");  
    printf("|            |         |                                          東昇苑 ====|                   |n");    
    printf("|            |         |                                                     |                   |n");
    printf("|            |       圖書館                                                  |                   |n");    
    printf("|       教學實驗樓     |                                                     |                   |n");     
    printf("|            |         |=====================================================|                   |n");     
    printf("|            |         |                 |||   西郵橋   |||                  |                   |n");
    printf("|  醫務室====|         |=====================================================|                   |n");
    printf("|                      |                                                                         |n");    
    printf("|                      |===體育館                                                                |n");     
    printf("|                      |                                                                         |n");    
    printf("|                      |                                                                         |n");    
    printf("|                    旭日苑                                                                      |n");     
    printf("|                      |                                                                         |n");
    printf("|                      |                                                                         |n");
    printf("|                  西區宿舍樓                                                                       |n");      
    printf("|                                                                                                |n");        
    printf("|------------------------------------------------------------------------------------------------|n");    
 } 
 
//建立圖,資訊從檔案中讀取 
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);  //從檔案中頂點的個數和邊的個數 
    G->vexnum = vexnum;
    G->arcnum = arcnum;    
    
    for(i = 1; i <= G->vexnum; i++){
        fscanf(fp2,"%sn%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);
}

//列印地點列表
void PrintPlace(AdjMatrix *G){ 
    int i;
    for(i = 1; i <= G->vexnum; i++ ){
        printf("tttttt%dt%sn",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( "tttttt——————地點資訊查詢——————n" );
        
        printf("tttttt請選擇需要查詢的方式n");
        printf("tttttt1.地點編號查詢n"); 
        printf("tttttt2.地點名稱查詢n"); 
        printf("tttttt3.地點編號名稱共同查詢n"); 
        
        scanf("%d",&c);
        
        if(c == 1){
            
            system("cls");

            PrintPlace(&G);
            
            printf( "tttttt請輸入需要查詢的地點編號:" );
            scanf( "%d", &num );
            
            if(num > 0 && num <= G.vexnum ){
                printf( "nn");
                printf( "ttt編號:%dn",num);
                printf( "ttt名稱:%sn", G.vex[num].name );
                printf( "ttt簡介:%snn", G.vex[num].info );
            }
            else{
                printf( "tttttt資訊輸入有誤!n" );
            }
            
            printf( "ntttttt是否繼續查詢地點資訊?n" );
            printf( "tttttt1:是n" );
            printf( "tttttt0:返回上級選單n" );
            scanf( "%d", &flag );
        }
        else if(c == 2){
            system("cls");
            printf("tttttt請輸入需要查詢的地點名稱:");
            scanf("%s",n);
            
            for(i = 1; i <= G.vexnum; i++ ){

                if(strcmp(G.vex[i].name,n) == 0){
                    
                    printf( "nn");
                    printf( "ttt編號:%dn",i);
                    printf( "ttt名稱:%sn", G.vex[i].name );
                    printf( "ttt簡介:%snn", G.vex[i].info );
                    break;
                }
               }

            printf( "ntttttt是否繼續查詢地點資訊?n" );
            printf( "tttttt1:是n" );
            printf( "tttttt0:返回上級選單n" );
            scanf( "%d", &flag );            
        }
        else if(c == 3){
            system("cls");
            PrintPlace(&G);
            printf( "tttttt請輸入需要查詢的地點編號:" );
            scanf( "%d", &num );
            printf("tttttt請輸入需要查詢的地點名稱:");
            scanf("%s",n);
            if(num > 0 && num <= G.vexnum && strcmp(G.vex[num].name,n) == 0){
                printf( "nn");
                printf( "ttt編號:%dn",num);
                printf( "ttt名稱:%sn", G.vex[num].name );
                printf( "ttt簡介:%snn", G.vex[num].info );
            }
            
            printf( "ntttttt是否繼續查詢地點資訊?n" );
            printf( "tttttt1:是n" );
            printf( "tttttt0:返回上級選單n" );
            scanf( "%d", &flag );
        }
    }
    system("cls");
}

//地點資訊,檔案 
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,"西區正門"); 
    strcpy(G.vex[1].info,"西安郵電大學長安校區西區的正門"); 
    strcpy(G.vex[2].name,"西郵橋"); 
    strcpy(G.vex[2].info,"連結西安郵電大學長安校區西區和東區的橋樑,過馬路請走西遊橋"); 
    strcpy(G.vex[3].name,"東區正門"); 
    strcpy(G.vex[3].info,"西安郵電大學長安校區東區的正門"); 
    strcpy(G.vex[4].name,"水煮鴿子"); 
    strcpy(G.vex[4].info,"西安郵電大學長安校區西區正門口,由鴿子和噴泉組成"); 
    strcpy(G.vex[5].name,"基礎教學樓"); 
    strcpy(G.vex[5].info,"西安郵電大學教學樓,有A樓和B樓,是西安郵電大學學生們上課的地方");
    strcpy(G.vex[6].name,"教學實驗樓"); 
    strcpy(G.vex[6].info,"西安郵電大學長安校區西區實驗樓");  
    strcpy(G.vex[7].name,"逸夫樓"); 
    strcpy(G.vex[7].info,"西安郵電大學教學樓,是學生們上課的地方,很容易迷路哦");   
    strcpy(G.vex[8].name,"圖書館"); 
    strcpy(G.vex[8].info,"西安郵電大學圖書館,可以借閱書籍和自習"); 
    strcpy(G.vex[9].name,"醫務室"); 
    strcpy(G.vex[9].info,"西安郵電大學醫務室"); 
    strcpy(G.vex[10].name,"旭日苑"); 
    strcpy(G.vex[10].info,"西安郵電大學西區食堂");
    strcpy(G.vex[11].name,"東昇苑"); 
    strcpy(G.vex[11].info,"西安郵電大學東區食堂");
    strcpy(G.vex[12].name,"體育館"); 
    strcpy(G.vex[12].info,"西安郵電大學體育館,內有運動場地"); 
    strcpy(G.vex[13].name,"西區宿舍"); 
    strcpy(G.vex[13].info,"分為長思公寓和長智公寓"); 
    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,"%sn%sn",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個頂點,24個邊
    fprintf(fp1,"%d %dn",G.vexnum,G.arcnum); //存入檔案標記
        //初始化矩陣 
    for(i = 0; i <= G.vexnum; i++){   
        for(j = 0; j <= G.vexnum; j++){ 
            G.arcs[i][j] = INFINITY;  //權值全部賦無窮大 
        } 
    }    
    
    //給地點設定權值,即需要走的路程 
    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 %10dn",i,j,G.arcs[i][j]);
                }
        }
    }
    fclose(fp1);
    fclose(fp);
}

//重置存取陣列 
void ClearVisited(AdjMatrix *G) {
    int i;
    for(i = 0; i <= MAXVEX; i++){
        G->vex[i].visited = 0; //全部置0 
    }
}

//深度優先搜尋遍歷 
void DfsAll(AdjMatrix *G,int s,int e){ 
    int i,j;    
    int shuai = 0;
    G->vex[s].visited = 1;  //置起始點為1 
    way1[count1] = s;    //把起點的序號存在一個陣列裡,此時count是0 
    
    for(i = 1; i <= G->vexnum; i++){  //遍歷頂點        
        if(G->arcs[s][i] != INFINITY && G->vex[i].visited == 0 && i != e){  //權值不等於無窮,而且沒有被存取過,並且沒有回到起點 
            count1++;  //陣列下標遞增 
            way1[count1] = i;  //給陣列對應的下標附上頂點值 
            DfsAll(G,i,e);  //遞迴 
            G->vex[i].visited = 0; //遞迴回來返回到這一層還原這一層現狀 
            count1--;
            shuai = 0;  //結束的標誌 
            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);  //起始點 
            for(j = 1;j <= count1; j++){
                printf("-->");
                printf("%s",G->vex[way1[j]].name);        //依次列印 
            }
            count1--;  //讓全域性變數count變成0,以供其它函數使用 
            return;
        }    
    }        
    return ; 
}

//所有簡單路徑選單 
void AllPath(AdjMatrix G,int dist[],int path[][MAXVEX]){  
    int s,e;
    int flag = 1;
    while(flag == 1){
        system("cls");
        printf( "tttttt——————所有簡單路徑查詢——————n" );
        
        PrintPlace(&G);
        
        printf("nttttt輸入起點編號:");
        scanf("%d",&s);
        printf("ttttt輸入終點編號:");
        scanf("%d",&e);
        
        if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e){
            printf( "tttttt輸入錯誤!nn" );
        }
        else{
            ClearVisited(&G);  //給標誌陣列初始化 
            count1=0;
            printf("nttt從%s到%s的所有簡單路徑有:n", G.vex[s].name, G.vex[e].name);
            
            DfsAll(&G,s,e); //呼叫函數進行實現功能 
        }
        printf("nntttttt是否繼續查詢所有簡單路徑?n" );
        printf("tttttt1:是n" );
        printf("tttttt0:返回上級選單n" );
        scanf("%d", &flag);
    }
    system("cls");
}

//中轉最少 ,也可以用廣搜,頂點A到頂點B所含邊的數目最少的路線,從A出發廣度優先遍歷,遇到頂點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;
        }  //此時搜到了所有路徑 
        
        
        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比最大頂點數小 
                minc = count2;   //就賦值 
                for(i = 0; i <= count2; i++){
                    minway[i]=way2[i];   //將記錄的way2值存到minway中 
                }
            }
            
            count2--;
            return;
        }    
    }        
}

//中轉次數最少簡單路徑
void LitterPath(AdjMatrix G){
    int i,j,s,e;
    int flag = 1;
    
    while (flag == 1){
        int i;
        system("cls");
        printf("tttttt——————中轉次數最少路徑查詢——————n");
        
        PrintPlace(&G);
        
        printf("nttttt輸入起點編號:");
        scanf( "%d", &s);
        printf("ttttt輸入終點編號:");
        scanf("%d", &e);
        if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e)
            printf("tttttt輸入錯誤!nn");
    
        else{
            ClearVisited(&G);
        
            minc = MAXVEX;
            
            count2 = 0;
        
            printf("nttt從%s到%s的中轉最少簡單路徑為:n", G.vex[s].name, G.vex[e].name);
            DfsLitter(&G,s,e);  //深搜尋找 
        
            printf("ttt%5s ",G.vex[minway[0]].name);
        
            for(i = 1; i <= minc; i++){    //mic即為count2 
                printf("-->");
                printf("%5s ",G.vex[minway[i]].name);
            }
            printf("nntttttt是否繼續查詢中轉最少簡單路徑?n");
            printf("tttttt1:是n");
            printf("tttttt0:返回上級選單n");
            scanf("%d", &flag);
            }
        system( "cls" );
    }
}

//最短路徑,dist陣列記錄各條最短路徑長度,path陣列記錄對應路徑上的各頂點 ,依最短路徑遞增次序求得各條路徑 
void Dijkstra(AdjMatrix *G,int s,int e,int dist[MAXVEX],int path[][MAXVEX]){  
    int mindist,i,j,k,t = 1;  //mindist 路徑的權值(長度) 
    
    for(i = 1; i <= G->vexnum; i++){  //給dist陣列初始化, 
        dist[i] = G->arcs[s][i]; //將鄰接陣列每一行所對應的列的值填入dist陣列中 
        
        if(G->arcs[s][i] != INFINITY){  //如果權值不等於無窮大,則說明有路
            path[i][1] = s;   //將起點記錄,path[i]記錄從源點到Vi最短路徑上的各個頂點
        } 
    }    
    
    path[s][0] = 1;   //置1標誌,說明源點為start 
    
    for(i = 2; i <= G->vexnum; i++){   //尋找各條最短路徑 
        
        mindist = INFINITY;  //將最小初值設定為無窮大 
        
        for(j = 1; j <= G->vexnum; j++){//選擇最小權值的路徑 
        
            if(!path[j][0] && dist[j] < mindist){//j未加入集合S  //path陣列記錄某定點是否加到S中 
                k = j;  //當前起點到頂點k權值最小
                mindist = dist[j];
            }
        }
            if(mindist == INFINITY){
                return;             //不存在start到其他頂點的路徑 
            }
            
            path[k][0] = 1;  // 將頂點k加入到集合S中,說明該頂點已經被考察 
            
            
            //看有沒有更小的,進而更新修改路徑 
            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行有路且未被選中過的頂點 &&到k的最小權值+k到j的權值<當前到j的最小權值路徑 
                    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;
                }
             }     
    }
}

//列印兩點間的最短路徑
void DijkstraPrint(int start, int end ,AdjMatrix G,int path[][MAXVEX]){
    int i = 2;
    int length = 0;
    printf( "nt從%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( ",長度為%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("tttttt——————最短路徑查詢——————n");
        PrintPlace(&G);
        printf("nttttt輸入起點編號:");
        scanf("%d",&s);
        printf("ttttt輸入終點編號:");
        scanf("%d",&e);
        if (s > G.vexnum || s <= 0 || e > G.vexnum || e < 0 || s == e){
            printf("tttttt輸入錯誤!nn");
        }
        else{
            ClearVisited(&G);   //選單 
            
            Dijkstra(&G,s,e,dist,path); //演演算法 
            DijkstraPrint(s,e,G,path);//列印 
    
        }
        printf("ntttttt是否繼續查詢最短路徑?n");
        printf("tttttt1:是n");
        printf("tttttt0:返回上級選單n");
        scanf("%d",&flag);
    }
    system("cls");
}

//路徑二級主選單 
void SearchPath(AdjMatrix G,int dist[],int path[][MAXVEX]){ 
    int x,flag = 1;
    while(flag == 1){  //二級選單 
        printf("ttt1. 所有簡單路徑n");  //各頂點均不重複 
        printf("ttt2. 最短的簡單路徑(中轉最少)n");
        printf("ttt3. 最佳存取路徑(最短路徑長度)n");
        printf("ttt0. 返回主選單n");
        printf("ttt請選擇您需要的操作:");
        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( "ttttttt輸入資訊錯誤,請重新輸入!n" ); break;
        }
    system("cls");
   }
}

//註冊資訊
void enroll(){
    char a[100];                   //註冊使用者名稱
    char b[100];                   //註冊密碼
    char s[100];                   //再次確定密碼
    int  len;
    
    
       printf("請輸入您的使用者名稱:");
    scanf("%s",a);
    
    printf("請設定您的密碼:");
            
    reset: scanf("%s",b);     //用到了if goto語句 

        len = strlen(b);    //讀取密碼長度 
       
        if(len > 9){
          printf("密碼長度過長,請重新設定:");
          goto reset;    //if goto 語句  
        }
           printf("請再次輸入您設定的密碼:");
         scanf("%s",s);
    
        if(strcmp(b,s) == 0){       //字串比較函數 
            FILE *fp;
        
            fp=fopen("register.txt","at");     //選用追加方式,可以存多個資訊
        
            if(fp == NULL){
                printf("檔案不存在或者請先註冊!");
                exit(1);                           
             }
        
            fprintf(fp,"%s %sn",a,b);                    //字串寫入函數進行寫入操作
            system("cls");
            printf("nt------註冊成功------n");
            fclose(fp);
        }
        else if(strcmp(b,s) != 0){
            printf("您兩次輸入的密碼不一致,請重新設定密碼!n");
            goto reset;          //if goto 語句 
        }
}

//登陸頁面
int land(){
    int  i = 0;      //i是為了判斷密碼長度 並加密 
    char a[10];                 
    char b[10];                   

    char user_name[10];           
    char user_passwords[10];      

    printf("請輸入您的使用者名稱:");
    scanf("%s",user_name);

    printf("請輸入您的密碼:");

    while(i < 9 && (user_passwords[i] = getch()) && user_passwords[i] != 'r'){   //如果輸入超限 或者 遇到換行符就跳出迴圈
        printf("*");   //掩飾密碼 
        i++;
    }
    
    user_passwords[i] = 0;   //字串結束標誌 '/0' 
    
    FILE *fp;
    fp=fopen("register.txt","rt");       //又開啟檔案 
    
    if(fp == NULL){
        printf("檔案不存在!");
        exit(1);
    }
    
    while(fscanf(fp,"%s %s",a,b) != EOF){    //讀檔案判斷賬號密碼是否正確     
        if(strcmp(a,user_name) == 0  &&  strcmp(b,user_passwords) == 0){   //字串比較函數,看是否正確 
             system("cls");
            printf("nttt--------登陸成功--------n");
            return 0;
         } 
    }
    if(1){
        system("cls");
        printf("n資訊輸入錯誤!(請檢查註冊檔案資訊)n");
        land();
    }
    fclose(fp);
}

//增加新地點和資訊 
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){
        //增加地點的地名
        //增加地點的介紹     
        
        printf("請輸入新地點的地名:");
        scanf("%s",p);    
        printf("請輸入新地點的簡介:");
        scanf("%s",i);    
    
        G->vexnum += 1;  //頂點數加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,"%sn%sn",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 %dn",G->vexnum,G->arcnum); 
    fclose(fp1);

    printf("tt新增地點成功,可開啟"introduce檔案"檢視!");  //跳脫字元 
    printf( "ntttttt是否繼續新增地點?n" );
    printf( "tttttt1:是n" );
    printf( "tttttt0:返回上級選單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);  //列印地點的序號 
    
           printf("請輸入增加路線的起點序號:");
        scanf("%d",&s);
        printf("請輸入增加路線的終點序號:");
        scanf("%d",&e);
    
        printf("請輸入兩條路線之間的距離:");
        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 %10dn",s,e,G->arcs[s][e]);
        fclose(fp);
        
        FILE *fp1;
        fp1 = fopen(filename1,"at");
        if(fp1 == NULL){
            printf("n不能開啟!");
            exit(1);
        }
        
        G->arcnum += 1; //邊數+1
        fprintf(fp1,"%d %dn",G->vexnum,G->arcnum); 
        fclose(fp1); 

        system("cls");
        printf("tt新增路線成功,可開啟"adj檔案"檢視!");  //跳脫字元 
        printf( "ntttttt是否繼續新增路線?n" );
        printf( "tttttt1:是n" );
        printf( "tttttt0:返回上級選單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("請輸入復原路線的起點序號:");
        scanf("%d",&s);
        printf("請輸入復原路線的終點序號:");
        scanf("%d",&e);
    
        //遍歷adj檔案,如果遍歷到s和e,那麼給它的值賦予無窮大        
           G->arcs[s][e] = G->arcs[e][s] = INFINITY;
          fprintf(fp,"%10d %10d %10dn",s,e,G->arcs[s][e]);
      
          G->arcnum -= 1; //邊數-1
        fprintf(fp1,"%d %dn",G->vexnum,G->arcnum); 
          fclose(fp); 
           fclose(fp1);
        system("cls");
        printf("tt復原路線成功,可開啟"adj檔案"檢視!");  //跳脫字元 
        printf( "ntttttt是否繼續復原路線?n" );
        printf( "tttttt1:是n" );
        printf( "tttttt0:返回上級選單n" );
        scanf( "%d", &flag );               
   } 
    system("cls");     
} 

//遊客
void User(){
    int x;
    int dist[MAXVEX];// 記錄各條最短路徑長度 
    int    path[MAXVEX][MAXVEX] = {0};//記錄對應路徑上的各頂點
    AdjMatrix G;   //鄰接矩陣   
    Create(&G); 
    while(1){
        printf("ttt1. 校園平面圖n");
        printf("ttt2. 地點資訊查詢n");
        printf("ttt3. 問路查詢n");
        printf("ttt0. 退出n"); 
        printf("ttt請選擇您需要的操作:");
        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("nttttttt"); exit(0); break;
        default: printf("n———————————————輸入資訊錯誤,請重新輸入!!!————————————————————n"); break;
        }
    } 
}

//管理員選單 
void OwnerMeau(AdjMatrix G){
    int c;
    int x;
    int dist[MAXVEX];// 記錄各條最短路徑長度 
    int    path[MAXVEX][MAXVEX] = {0};//記錄對應路徑上的各頂點
    while(1){
        printf("ttt1. 新增新地點n");
        printf("ttt2. 新增新路線n");
        printf("ttt3. 復原舊路線n");
        printf("ttt4. 校園平面圖n");
        printf("ttt5. 地點資訊查詢n");
        printf("ttt6. 問路查詢n");
        printf("ttt0. 退出n"); 
        printf("ttt請選擇您需要的操作:");
        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("nttttttt"); exit(0);
            default: printf("n———————————————輸入資訊錯誤,請重新輸入!!!————————————————————n"); break;    
        }
    }
}

//管理員登入 
void Owner(){
    int x;
    int dist[MAXVEX];// 記錄各條最短路徑長度 
    int    path[MAXVEX][MAXVEX] = {0};//記錄對應路徑上的各頂點
    AdjMatrix G;   //領接矩陣 
    MapFile(G); 
    IntroduceFile(G);  //向檔案中存入介紹資訊 
    AdjFile(G);    //向檔案中存入鄰接矩陣資訊 
    Create(&G);
    
    system("cls");
    printf("tt1.登陸ttt2.註冊並登入n");
    printf("請選擇序號:");
    
    while(1){
        scanf("%d",&x);
        switch(x){
             case 1:  land(); OwnerMeau(G); break;
            case 2:  enroll(); land(); OwnerMeau(G); break;
            default: printf( "n———————————————輸入無效,請重新正確輸入!!!————————————————————n"); break;
        }        
    } 
}

//主函數 
int main(){
     int flag;
    
    printf("——————————————————————————————————————————————n"); 
    printf("nttt歡迎使用西安郵電大學長安校區導遊系統 !nn");   
    printf("——————————————————————————————————————————————n");
    printf("nnn"); 
    
    //遊客or管理員 
    printf("tt1.我是遊客ttt2.我是管理員n");
    printf("請選擇序號:");
    
    while(1){
        scanf("%d",&flag);
        switch(flag){
             case 1: system("cls"); User(); break;
            case 2: system("cls"); Owner(); break;
            default: printf("n———————————————輸入無效,請重新正確輸入!!!————————————————————n"); break;
        }
    } 
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com