校園導航系統(數據結構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文章。
這是我自己寫的,函數參考了《大話數據結構》一書;
推薦給學數據結構的你。
堅持自己的學習之路。