执行过程
步骤 | S集合中 | U集合中 |
1 | 选入A,此时S ={A} 此时最短路径A->A = 0 以A为中间点,从A开始找 | U = {B, C, D, E, F} A->B = 6 A->C = 3 A->U中其他顶点 = ∞ 其中A->C = 3 权值为最小,路径最短 |
2 | 选入上一轮中找到的最短路径的顶点C,此时S = {A, C} 此时最短路径A->A = 0,A->C = 3 以C为中间点,从A->C=3这条最短路径开始新一轮查找 | U = {B, D, E, F} A->C->B = 5(比上面的A->B = 6要小) 替换B的权值为更小的A->C->B = 5 A->C->D = 6 A->C->E = 7 A->C->U中其他顶点 = ∞ 其中A->C->B = 5 最短 |
3 | 选入B,此时S = {A, C, B} 此时最短路径 A->A = 0,A->C = 3 A->C->B = 5 以B为中间点,从A->C->B = 5这条最短路径开始新一轮查找 | U = {D, E, F} A->C->B->D = 10(比上面的A->C->D = 6大,不替换,保持D的权值为A->C->D=6) A->C->B->U中其他顶点 = ∞ 其中 A->C->D = 6 最短 |
4 | 选入D,此时 S = {A, C, B, D} 此时最短路径 A->A = 0,A->C = 3,A->C->B = 5,A->C->D = 6 以D为中间点,从A->C->D = 6这条最短路径开始新一轮查找 | U = {E, F} A->C->D->E = 8(比上面步骤2中的A->C->E = 7要长,保持E的权值为A->C->E =7) A->C->D->F = 9 其中A->C->E = 7最短 |
5 | 选入E,此时 S = {A, C, B, D ,E} 此时最短路径 A->A = 0,A->C = 3,A->C->B = 5,A->C->D = 6,A->C->E =7, 以E为中间点,从A->C->E = 7这条最短路径开始新一轮查找 | U = {F} A->C->E->F = 12(比第4步中的A->C->D->F = 9要长,保持F的权值为A->C->D->F = 9) 其中A->C->D->F =9最短 |
6 | 选入F,此时 S = {A, C, B, D ,E, F} 此时最短路径 A->A = 0,A->C = 3,A->C->B = 5,A->C->D = 6,A->C->E =7,A->C->D->F = 9 | U集合已空,查找完毕 |
代码如下:
/*
严蔚敏 dijkstra 算法
D和min的变化
0 5 3 6 7 MAX min 3
0 5 3 6 7 MAX min 5
0 5 3 6 7 9 min 6
0 5 3 6 7 9 min 7
0 5 3 6 7 9 min 9
*/
#include <iostream>
#include <cstdio>
#define MAX 999
using namespace std;
int arcs[10][10];//邻接矩阵
int D[10];//保存最短路径长度
int final[10];//若final[i] = 1则说明 顶点vi已在集合S中
int n = 0;//顶点个数
int v0 = 0;//源点
int v, w;
/* 若要求所有点到其它点的最短路径,只需要在函数中加一个形参N,然后初始化时D[i] = arcs[N][i]; 起初的final[N]=1;就ok了*/
void ShortestPath_DIJ()
{
//初始化
for (int i = 0; i < n; i++)
{
D[i] = arcs[0][i];
final[i] = 0;
}
final[0] = 1;
for (int i = 0; i < n; i++)
{
int min = MAX;
for (v = 0; v < n; v++)
{
if (final[v] == 0)//点不在S中
{
//找出与当前靠近的且权值最小的点
if (D[v] < min)
{
w = v;
min = D[v];
}
}
}
final[w] = 1; //当前选出了一个点,加入集合s中
//下面这个for的作用是更新最短路径
for (int j = 0;j < n; j++)
{
if (final[j] == 0 && D[j]> min + arcs[w][j])
{
D[j] = min + arcs[w][j];
}
}
//此处在第一次循环结束时,D[]里存放的最短路径已经更改了
}
}
void Print();//输出邻接矩阵的函数声明
int main()
{
n = 6;
//若两点之间不可达则用MAX来代替
int arry[36] = { 0,6,3,MAX,MAX,MAX,6,0,2,5,MAX ,MAX ,3,2,0,3,4,MAX ,MAX ,5,3,0,2,3,MAX ,MAX ,4,2,0,5,MAX ,MAX ,MAX ,3,5,0 };
int idx = 0;
for(int i=0;i<6;i++)
for (int j = 0; j < 6; j++)
{
arcs[i][j] = arry[idx++];
}
Print();
ShortestPath_DIJ();
for (int i = 0; i < n; i++)
printf("D[%d] = %d\n", i, D[i]);
system("pause");
return 0;
}
/*
D[0] = 0
D[1] = 5
D[2] = 3
D[3] = 6
D[4] = 7
D[5] = 9
*/
void Print()
{
cout << "邻接矩阵为: " << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout.width(7);
cout<< arcs[i][j];
}
cout << endl;
}
}