本文以最简洁的方式描述Dijkstra算法,如下图所示:
上图数据保存于如下二维数组G(Graph)中:
int G[5][5] = { {0, 9, 1, INF, 3 },
{9, 0, 5, INF, INF },
{1, 5, 0, 7, 4 },
{INF, INF, 7, 0, 6 },
{3, INF, 4, 6, 0 } };
存储五个顶点中每个顶点与其他顶点对应的边长(未连接用INF表示,自身的边长为0)。过程主要分为如下三部分:
一、初始化;
while (节点没有标记完)
{
二、找最小距离节点,标记访问过;
三、更新dist数组;
}
说明:
一、初始化:
1. 初始化visit数组。记录某个节点是否已经访问过。
2. 初始化dist数组。dist(distance)数组就是源节点到另外各个节点的最短路径数组,也就是我们要得到的结果数组,如果是A节点为源节点,那么初始化将G中第一行距离值复制到dist数组中即可;
二、找最小距离节点,标记访问过:
从dist数组中找到数值最小的一个节点,记录数值min和索引minIndex。
三、 更新dist数组:
从图中看出,初始化A到D的距离是INF的,那么以B为中间点的话,A到D的dist[3]值就从INF更新为8了。
手动执行过程:
测试代码如下:
#include <iostream>
using namespace std;
const int LEN = 5;
const int INF = 65535;
void dijkstra(int G[5][5], int src, int* dist)
{
bool visit[LEN] = { false };
visit[src] = true;
int min, minIndex;
for (int i = 0; i < LEN; ++i)
dist[i] = G[src][i];
for (int i = 0; i < LEN; ++i)
{
min = INF;
for (int j = 0; j < LEN; ++j)
{
if (!visit[j] && dist[j] < min)
{
min = dist[j];
minIndex = j;
}
}
visit[minIndex] = true;
for (int j = 1; j < LEN; ++j)
{
if (!visit[j] && G[minIndex][j] + min < dist[j])
dist[j] = G[minIndex][j] + min;
}
}
}
int main()
{
int G[5][5] = { {0, 9, 1, INF, 3 },
{9, 0, 5, INF, INF },
{1, 5, 0, 7, 4 },
{INF, INF, 7, 0, 6 },
{3, INF, 4, 6, 0 } };
int dist[5];
dijkstra(G, 0, dist);
for (int i = 0; i < 5; ++i)
cout << dist[i] << " ";
return 0;
}
结果:0 6 1 8 3
和手动观察计算结果一致。