Dijkstra算法用来寻找图的结点间最短路径,通常是指定一个起始结点后,寻找从该结点出发,到达各个结点的最短路径。该算法是有关最短路径问题的一个算法。由Dijkstra于1959年提出。
百度百科:Dijkstra算法。
维基百科:Dijkstra's Algorithm。
参考链接:Dijkstra算法的C语言程序。
程序说明:图存储在二维数组中,即邻接矩阵中。使用s集合和vs集合辅助Dijkstra算法的过程,开始时将指定的开始结点放入s集合中,其他剩余的结点放入vs集合中,从s集合到vs集合的边中找出一个代价最小的边,然后将相关的结点从vs集合取出放入s集合,指定所有结点都在s集合为止。
中间结果和最后结果放在数组dist[]中。
C语言程序:
/* Dijkstra算法程序 */ #define MAX_INT (int)((unsigned)(-1) >> 1) #define MIN(x, y) ((x)>(y))?(y):(x) #define TRUE 1 #define FALSE 0 #include <stdio.h> //假设有N个节点其中包含1个源点,N-1个终点求源点到其他节点的最短路径 #define N 6 int a[N][N]; int dist[N]; int prev[N]; int s_set[N], s_count; int vs_set[N], vs_count; void createMatrix(); void init(int s); void dijkstra(); int main(void) { int i, j, s; createMatrix(); for(i=0; i<N; i++) { for(j=0; j<N; j++) printf("%4d", a[i][j]); printf(" "); } printf("start node:"); scanf("%d", &s); if(s>=0 && s<=N-1) { init(s); } else printf("input error! "); printf("first distance: "); for(i=0; i<N; i++) printf("%12d", dist[i]); printf(" "); dijkstra(); printf("result distance: "); for(i=0; i<N; i++) printf("%4d ", dist[i]); printf(" "); printf("result previous: "); for(i=0; i<N; i++) printf("%4d ", prev[i]); printf(" "); return 0; } void dijkstra() { int i, j, minval, pm; for(;;) { if(vs_count == 0) return; minval=MAX_INT; for(i=0; i<N; i++) { if(vs_set[i]) { minval = MIN(minval, dist[i]); if(minval == dist[i]) pm = i; } } s_set[pm] = TRUE; s_count++; vs_set[pm] = FALSE; vs_count--; for(i=0; i<N; i++) if(s_set[i]) for(j=0; j<N; j++) if(vs_set[j] && a[i][j]!=-1) { int temp = MIN(dist[j], dist[i]+a[i][j]); if(temp < dist[j]) { dist[j] = temp; prev[j] = i; } } } } //创建邻接矩阵 void createMatrix() { int i, j; for(i=0; i<N; i++) for(j=0; j<N; j++) if(i==j) a[i][j] = 0; else a[i][j] = -1; FILE *fp; fp = fopen("d1.txt", "r"); for(;;) { int val; fscanf(fp, "%d%d%d", &i, & j, &val); if(i == -1) break; a[i][j] = val; } fclose(fp); } void init(int s) { int i; for(i=0; i<N; i++) dist[i] = (a[s][i]==-1)?MAX_INT:a[s][i]; for(i=0; i<N; i++) prev[i] = s; for(i=0; i<N; i++) { s_set[i] = FALSE; vs_set[i] = TRUE; } s_set[s] = TRUE; s_count = 1; vs_set[s] = FALSE; vs_count = N-1; }
输入数据(文件):
0 2 10 0 1 50 0 4 70 1 2 15 1 4 10 2 0 20 2 3 15 3 1 20 3 4 35 4 3 30 5 3 3 -1 -1 -1
输出结果:
0 50 10 -1 70 -1 -1 0 15 -1 10 -1 20 -1 0 15 -1 -1 -1 20 -1 0 35 -1 -1 -1 -1 30 0 -1 -1 -1 -1 3 -1 0 start node:1 first distance: 2147483647 0 15 2147483647 10 2147483647 result distance: 35 0 15 30 10 2147483647 result previous: 2 1 1 2 1 1