校園導航系統(數據結構C語言鄰接矩陣爲存儲結構和迪傑斯特拉算法求最短距離)

校園導航系統(數據結構C語言實現)

開發工具:Dev-C++;
(1)設計任務
掌握圖的結構特點及應用,運用所學知識解決現實問題。給出校園各主要建築的名稱信息及有線路聯通的建築之間的距離,利用校園導航系統計算出輸入的起點到終點之間的最近距離及線路。
(2)設計要求
①輸入各建築信息及線路信息,構建圖。本項目數據結構爲有向網,採用鄰接矩陣爲存儲結構。
②計算給定起點到終點之間最近距離的進行線路。參照迪傑斯特拉算法計算給定兩點之間的最短路徑。
③根據輸入起點和終點,輸出線路及總距離。

說明:
採用鄰接矩陣爲存儲結構和迪傑斯特拉算法求最短距離實現功能;
代碼已經爲輸入值賦值,可以自行修改相關代碼;
創建圖的函數也已經爲圖的各個頂點和權值賦值,可以自己修改;
主函數中有輸出全部結果的相關代碼;


#include "stdio.h"    
#include"string.h"
#define MAXVEX 20 		  //最大頂點數     
#define INFINITY 65535    //65535代表 ∞     
#define TRUE 1    
#define FALSE 0    
#define OK 1    
#define ERROR 0

   
typedef int Status;	    			/* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */ 
typedef char    VertexType;    //頂點類型 
typedef int EdgeType;            //邊的權值類型 
typedef int    Patharc[MAXVEX];                /* 用於存儲最短路徑下標的數組 */ 
typedef int    ShortPathTable[MAXVEX];  /* 用於存儲到各點最短路徑的權值和 */
 
typedef struct 
{ 	
	 VertexType vexs[MAXVEX][MAXVEX];     //頂點表 	
	 EdgeType    arc[MAXVEX][MAXVEX];     //鄰接矩陣 	
	 int numVertexes, numEdges;                   //圖中當前頂點數和邊數 
} MGraph;
   
void CreateMGraph(MGraph *G);//鄰接矩陣創建網圖 
void map();//地圖 
void    ShortestPath_Dijkstra(MGraph G, int v0, Patharc *P, ShortPathTable    *D); /*---迪傑斯特拉算法---*/
       
int main() 
{ 	
    int i,j,v0,v1,a[MAXVEX]; 	MGraph G; 	Patharc P;
	ShortPathTable D; /* 求某點到其餘各點的最短路徑 */
   
   
    printf("\n"); 	
    CreateMGraph(&G); 	
    printf("\n");
	   
    map();//校園地圖
   
   	v0=0; 	
   	printf("\n輸入起始點序號:%d",v0); 	//printf("\n輸入起始點序號:");
   	//scanf("%d",&v0);
   
   	ShortestPath_Dijkstra(G, v0, &P, &D);
   
   	//v0-->v1的最短距離 	v1=5; 	printf("\n輸入終點點序號:%d\n",v1);
   	//printf("\n輸入終點點序號:"); 	//scanf("%d",&v1);
   
   
   	printf("\n%s ---->%s 的最短路徑長度爲: %d \n",G.vexs[v0],G.vexs[v1],D[v1]);
   
   	j=v1; 	
   	for(i=0; P[j]!=-1; i++)  	{ 		a[i]=P[j]; 		j=P[j]; 	}
   
   	printf("\n%s ----> %s 的路徑爲:  \n",G.vexs[v0],G.vexs[v1]); 	
   	j=v1;
   	printf("%s---->",G.vexs[v0]); 	
   	for(i--; i>=0; i-- ) 
   		printf("%s---->",G.vexs[a[i]]);
   
   
   	printf("%s",G.vexs[v1]); 	printf("\n");
   
   
        	/* 	
		   	//算法的全部可能結果  	
		   	for(int k=0;k<G.numVertexes;k++) 	
		   	{ 		v0=k;
		   		ShortestPath_Dijkstra(G, v0, &P, &D);
		       
		   	    printf("最短路徑倒序如下:\n");
		   	    for(i=1; i<G.numVertexes; ++i)  		
		   	    {
		   		  printf("%s---->%s的最短路徑長度: %d ",G.vexs[v0],G.vexs[i],D[i]);
		   		  printf("%s---->%s的路徑: ",G.vexs[v0],G.vexs[i]);
		   		  j=i;
		   		  printf("%s",G.vexs[i]);
		   		  while(P[j]!=-1) 
		   		     { 			printf("<----%s ",G.vexs[P[j]]); 			
		   		  				j=P[j];
		   		      }
		   		   
		   		  printf("<----%s \n",G.vexs[v0]);
		   		  printf("\n");
		   	    } 	 	
		   	 } 	
   	   */
   
   	return 0; 
   	}
   
   
   
   
   
       /* 構造圖 */ 
 void CreateMGraph(MGraph *G) 
 { 	
	  int i,j,k,w;
	   
	   	printf("輸入頂點數和邊數:\n");
	   	//scanf("%d%d",&G->numVertexes,&G->numEdges);
	    //輸入頂點數和邊數
	   	G->numEdges=32; 	G->numVertexes=17; 	
	   	printf("numVertexes=%d;    numEdges=%d",G->numVertexes,G->numEdges);
	   
	   	printf("\n輸入頂點信息,建立頂點表:\n");
	   	
	   	/*
	   	for(i=0;i<G->numVertexes;i++)//讀入頂點信息,建立頂點表
	   		scanf("%s",&G->vexs[i]);
	   	*/
	   
	   	strcpy(G->vexs[0],"南門"); 	strcpy(G->vexs[1],"東門");
	   	strcpy(G->vexs[2],"北門"); 	strcpy(G->vexs[3],"A樓");
	   	strcpy(G->vexs[4],"B樓"); 	strcpy(G->vexs[5],"一食堂");
	   	strcpy(G->vexs[6],"綜合樓"); 	strcpy(G->vexs[7],"聚龍湖");
	   	strcpy(G->vexs[8],"C樓"); 	strcpy(G->vexs[9],"E樓");
	   	strcpy(G->vexs[10],"D樓"); 	strcpy(G->vexs[11],"爾雅");
	   	strcpy(G->vexs[12],"圖書館"); 	strcpy(G->vexs[13],"耘慧");
	   	strcpy(G->vexs[14],"靖遠"); 	strcpy(G->vexs[15],"新體育場");
	   	strcpy(G->vexs[16],"行政樓");
	   
	   	for(j=0; j<G->numVertexes; j++) 
	   	{ 		
	   		printf(" %d.%s ",j,G->vexs[j]);
	   		if(j!=0&&j%6==0) printf(" \n"); 	
	   	} 	
	   		printf(" \n\n");
	   
	   
	   	for(i=0; i<G->numVertexes; i++) //鄰接矩陣初始化 		
	   	for(j=0;    j<G->numVertexes; j++) 			
	   			G->arc[i][j]=INFINITY; 	
	   	
	   	/*
	   	for(k=0;k<G->numEdges;k++) 	
	   	{ 		
	   			printf("輸入邊(vi,vj)上    的下標i,下標j和權w;\n"); 		
	   			scanf("%d%d%d",&i,&j,&w);//輸入邊和權
	   
	   		G->arc[i][j]=w; 		//printf("i=%d,j=%d,G->arc[i][j]=%d",i,j,w);
	   		G->arc[j][i]=G->arc[i][j];//無向圖矩陣對稱 	 
	   	} 	 
	   	*/
	   
	   	G->arc[0][14]=G->arc[14][0]=10; 	G->arc[0][16]=G->arc[16][0]=4;
	   	G->arc[0][15]=G->arc[15][0]=13;
	   
	   	G->arc[1][8]=G->arc[8][1]=8; 	G->arc[1][9]=G->arc[9][1]=7;
	   
	   	G->arc[2][3]=G->arc[3][2]=5; 	G->arc[2][11]=G->arc[11][2]=20;
	   
	   	G->arc[3][4]=G->arc[4][3]=2; 	G->arc[3][5]=G->arc[5][3]=3;
	   
	   	G->arc[4][5]=G->arc[5][4]=2; 	G->arc[4][6]=G->arc[6][4]=3;
	   
	   	G->arc[5][6]=G->arc[6][5]=1; 	G->arc[5][11]=G->arc[11][5]=10;
	   
	   	G->arc[6][11]=G->arc[11][6]=9; 	G->arc[6][7]=G->arc[7][6]=3;
	   	G->arc[6][8]=G->arc[8][6]=4;
	   
	   	G->arc[7][8]=G->arc[8][7]=5; 	G->arc[7][11]=G->arc[11][7]=4;
	   	G->arc[7][15]=G->arc[15][7]=7; 	G->arc[7][12]=G->arc[12][7]=5;
	   	G->arc[7][13]=G->arc[12][7]=6; 	G->arc[7][14]=G->arc[14][7]=7;
	   
	   	G->arc[8][9]=G->arc[9][8]=2; 	G->arc[8][10]=G->arc[10][8]=2;
	   
	   	G->arc[9][10]=G->arc[10][9]=3;
	   
	   	G->arc[10][15]=G->arc[15][10]=1;
	   
	   	G->arc[11][12]=G->arc[12][11]=1;
	   
	   	G->arc[12][13]=G->arc[13][12]=1;
	   
	   	G->arc[13][14]=G->arc[14][13]=1; 	G->arc[13][16]=G->arc[16][13]=3;
	   
	   	G->arc[14][16]=G->arc[16][14]=2;
	   
	   	G->arc[15][16]=G->arc[16][15]=10;
	   
	   
	   	for(i = 0; i < G->numVertexes; i++) 
	   	{ 		
	   			for(j = i; j <    G->numVertexes; j++) 
	   			{ 			G->arc[j][i] =G->arc[i][j]; 		} 	
	   			}
	       }


	       /*  Dijkstra算法,求有向網G的v0頂點到其餘頂點v的最短路徑P[v]及帶權長度D[v] */ /*     P[v]的值爲前驅頂點下標,D[v]表示v0到v的最短路徑長度和 */ 
	       void ShortestPath_Dijkstra(MGraph    G, int v0, Patharc *P, ShortPathTable    *D) 
	       { 	
				       int v,w,k,min; 	
				       int final[MAXVEX];/* 
				       final[w]=1表示求得頂點v0至vw的最短路徑 */ 	
				       for(v=0; v<G.numVertexes; v++) 
					   {  
					       /*    初始化數據 */ 		
					       final[v] = 0;			
					       /* 全部頂點初始化爲未知最短路徑狀態 */ 		
					       (*D)[v] =    G.arc[v0][v];
					       /* 將與v0點有連線的頂點加上權值 */ 		
					       (*P)[v] = -1;				/* 初始化路徑數組P爲-1    */ 	
					    }
					   
					   	(*D)[v0] = 0;  /* v0至v0路徑爲0 */ 	
					   	final[v0] = 1;    /* v0至v0不需要求路徑 */
					   	/* 開始主循環,每次求得v0到某個v頂點的最短路徑 */ 	
					   	for(v=1; v<G.numVertexes; v++)  	
					   	{
					   		min=INFINITY;    /* 當前所知離v0頂點的最近距離 */ 		
					   		for(w=0; w<G.numVertexes;    w++) 		 
						   		{ /* 尋找離v0最近的頂點 */ 			
							   		if(!final[w] && (*D)[w]<min) 
								   		{
								   				k=w;
								   				min = (*D)[w];    /* w頂點離v0頂點更近 */ 			
								   		} 		
						   		} 		
					   		final[k] = 1;    /* 將目前找到的最近的頂點置爲1 */ 		
					   		for(w=0; w<G.numVertexes; w++) 
					   	    {       /* 修正當前最短路徑及距離    */ 			
					   				/* 如果經過v頂點的路徑比現在這條路徑的長度短的話 */ 			
					   				if(!final[w] && (min+G.arc[k][w]<(*D)[w]))
						   				 {
							   				/*  說明找到了更短的路徑,修改D[w]和P[w] */
							   				(*D)[w] = min + G.arc[k][w];  /* 修改當前路徑長度 */
							   				(*P)[w]=k; 			
						   				} 		
					   			} 	
					   	  } 
           }
   
       void map() 
       {
			   	printf("     *  2.北門*********************************************      \n"); 	
			   	printf("     *      3.A樓             4.B樓                        *   \n"); 	
			   	printf("     *		 5.一食堂                                         \n"); 	
			   	printf("     *                                               1.  \n"); 	
			   	printf("     *              6.綜合樓                               東   \n"); 	
			   	printf("     *                                               門   \n"); 	
			   	printf("     *                                               *   \n"); 	
			   	printf("     *	      7.聚龍湖		                                   \n"); 	
			   	printf("     *                                 8.C樓   \n");       
			   	printf("     *              6.綜合樓                               東   \n"); 	
			   	printf("     *                                               門   \n"); 	
			   	printf("     *                                               *   \n"); 	
			   	printf("     *	      7.聚龍湖		                                   \n"); 	
			   	printf("     *                                 8.C樓        9.E樓   *   \n"); 	
			   	printf("     *11.爾雅			          10.D樓	                   \n"); 	
			    printf("     *12.圖書館                                             *   \n"); 	
			    printf("     *13.耘慧		16行政樓		                           \n"); 	
	            printf("     *14.靖遠				15.新體育場                       \n");
			   	printf("     *                                                         *   \n"); 	
			   	printf("     *				                                           \n"); 	
			   	printf("     *                                                   *   \n"); 	
			   	printf("     ******************0.南門*****************************      \n");
    }
   

代碼運行結果
運行結果

2019.1.12第一篇CSDN文章。
這是我自己寫的,函數參考了《大話數據結構》一書;
推薦給學數據結構的你。
堅持自己的學習之路。

發佈了9 篇原創文章 · 獲贊 14 · 訪問量 3338
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章