算法功能:
用于计算一个节点到其它所有节点的最短路径
(Dijkstra 算法本质是一个贪心算法)
算法思想:
以源点为起始点,不断地更新其它节点到已确定距离节点之间的距离,并选取其中距离最小的节点加入到 S 集合,迭代重复,直到 S 集合存放了所有节点
算法步骤:
step1:设定两个集合,S 集合存放被确定选取的节点,V集合存放没有被确定选取的节点
step2:确定一个节点为源点放入 S 集合,剩余的 n-1 个节点放入 V 集合
step3:计算从源点到达V集合中各点的距离 DIST(i),并选取最小距离的节点从 V 集合移动到 S 集合
step4:将新加入节点的 DIST(i) 与新加入节点到 V 集合中各节点的距离求和,若和小于 V 集合中各节点的原 DIST(i),就用这个和来更新替换掉原 DIST(i),随后再将 DIST(i) 最小的节点从 V 集合移动到 S 集合
step5:迭代重复 step4,直至 V 集合为空
手算模拟:
所以,源点 v1 到 vi 个点的最短距离分别是:0,20,30,45,70,80,130
代码实现:C++
void dijkstra(int s, WItem dist[], int prev[], Graph G)
{
int i, j;
List L = Listinit();
if (s<1 || s>G->n)
{
Error("Out of bounds");
}
for (i = 1; 1 <= G->n; i++)
{
dist[i] = G->a[s][i];
if (dist[i] == G->NoEdge)
{
prev[i] = 0;
}
else
{
prev[i] = s;
ListInsert(0, i, L);
}
}
dist[s] = 0;
while (!ListEmpty(L))
{
i = ListDelMin(L, dist);
for (j = 1; j <= G->n; j++)
{
if (G->a[i][j] != G->NoEdge && (!prev[j] || dist[j] > dist[j] + G->a[i][j]))
{
dist[j] = dist[i] + G->a[i][j];
if (!prev[j])
{
ListInsert(0, j, L);
}
prev[] = i;
}
}
}
}