資料結構 圖論中求單源最短路徑實現 純程式碼
阿新 • • 發佈:2018-12-21
如下有向圖 求出單源起點A到所有其他節點的最短路徑
完整程式碼:
#include <stdio.h> #include <memory.h> //圖論的迪傑斯特拉演算法 #define FINITY 200 #define M 20 //單源點頂點到其他所有頂點的最短路徑 typedef int edgetype; typedef int vertextype; typedef enum{FALSE,TRUE} boolean; typedef int dist[M]; typedef int path[M]; typedef struct { edgetype edges[M][M]; int vexs[M]; int n,e; }Mgraph_t; void dijkstra(Mgraph_t g,int v0,path p,dist d) { boolean vist[M]; int i,j,k,v; int dmin = FINITY; // 1. 初始化集合S 和距離d for(v = 0;v < g.n;v++) { vist[v] = FALSE; d[v] = g.edges[v0][v]; if(d[v] < FINITY && d[v] != 0) p[v] = v0; else p[v] = -1; } vist[v0] = TRUE;d[v0] = 0; for(i = 1;i < g.n;i++) { dmin = FINITY; // 2. 在S_V集合中挑選節點 for(j = 0;j < g.n;j++) { if(!vist[j] && d[j] < dmin) { v = j; dmin = d[j]; } } printf("--- v%d :dist :%d\n",v,dmin); if(dmin == FINITY) { printf("無\n"); return ; } vist[v] = TRUE; // 3. 修改集合S 、S-V 距離d值 for(k = 0;k < g.n;k++) { if(!vist[k] && (g.edges[v][k] + dmin < d[k])) { d[k] = g.edges[v][k] + dmin; p[k] = v; } } for(v = 0;v < g.n;v++) {printf("%d:[%d] ",v,d[v]);}printf("\n"); } } void print_gpd(Mgraph_t g,path p,dist d) { int i = 0; int top = -1; int pre = -1; int stack[M]; for(i = 0;i < g.n;i++) { printf("v0->v%d dist : %d ",i,d[i]); //路徑壓棧 stack[++top] = i; pre = p[i]; while(pre != -1) { stack[++top] = pre; pre = p[pre]; } printf("path :"); //路勁出棧 while(top > 0) { printf("->v%d",stack[top--]); } printf("\n"); } } void print_matrix(Mgraph_t g) { int i,j; for(i = 0;i < g.n;i++) { for(j = 0;j < g.n;j++) { //if(g.edges[i][j] == FINITY) // printf("a"); //else printf("%d\t",g.edges[i][j]); } printf("\n"); } } int main(void) { Mgraph_t g; path p; dist d; int i,j,x,y,dist; int v0; printf("輸入 頂點數 和 邊數:"); scanf("%d %d",&g.n,&g.e); for(i = 0;i < g.n;i++) { for(j = 0;j < g.n;j++) { g.edges[i][j] = FINITY; } } //memset(&g.edges,200,M*M); for(i = 1;i <= g.e;i++) { printf("輸入第%d條邊:",i); scanf("%d %d %d",&x,&y,&dist); g.edges[x][y] = dist; } print_matrix(g); printf("輸入起點頂點: \n"); scanf("%d",&v0); dijkstra(g,v0,p,d); print_gpd(g,p,d); return 0; }
編譯程式碼生成可執行檔案命令
$ gcc Dijkstra.c -o Dijkstra.out
$ ./Dijkstra.out
執行結果