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("\n");
}
printf("start node:");
scanf("%d", &s);
if(s>=0 && s<=N-1) {
init(s);
} else
printf("input error!\n");
printf("first distance:\n");
for(i=0; i<N; i++)
printf("%12d", dist[i]);
printf("\n");
dijkstra();
printf("result distance:\n");
for(i=0; i<N; i++)
printf("%4d ", dist[i]);
printf("\n");
printf("result previous:\n");
for(i=0; i<N; i++)
printf("%4d ", prev[i]);
printf("\n");
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