一.算法思想
将所有节点分为两组,一组节点是,从起点到该点的最短路径已经被确认,而另外一组是未被确定最短路径的节点。一开始,只有起点的最短路径被确认,并且为0,然后它遍历其他节点,并不断更新从起点到当前节点的最短路径。直到该点被访问后,则该点的最短路径被确定。
二.如下图所示,用Dijkstra算法找出节点O到T的最短路径
(1)首先初始化起点最短路径L(O)=0,剩下的点L(A)=L(B)=L(C)=L(D)=L(E)=L(F)=L(T)=∞;S是所有被遍历过的节点集合。U是当前被遍历的节点,W(Vi,Ui)表示两个节点的权值。
通过判断当前节点的最短路径加上到下一个节点的权值来确定下一个节点的最短路径,并不断迭代。
第一次迭代,U=O,和S={O}; L(O)+W(O,A)=2<L(A);
L(O)+W(O,B)=5<L(B);
L(O)+W(O,C)=4<L(C);
更新上面3个点的最短路径:L(A)=2,L(B)=5,L(C)=4;
第二次迭代 U=A,S={O,A}
L(A)+W(A,B)=4<L(B);
L(A)+W(A,F)=14<L(F);
L(A)+W(A,D)=9<L(D);
更新上面三个点的最短路径L(B)=4,L(F)=14,L(D)=9
第三次迭代U=B、S={O、A、B}
L(B)+W(B,D)=8<L(D);
L(B)+W(B,E)=7<L(E);
更新上述两点的最短路径 L(D)=8,L(E)=7;
第四次迭代U=C、S={O,A、B、C}
L(C)+W(C,E)=8>L(E);
没有更新点。
第五次迭代U=D、S={O、A、B、C、D}
L(D)+W(D,T)=13<L(T);
将最短路径更新到上面节点 L(T)=13;
第六次迭代U=E、S={O、A、B、C、D、E}
L(E)+W(E,T)=14>L(T);
无更新点
第七次迭代U=F、S={O、A、B、C、D、E、F}
L(F)+W(F,T)=17>L(T)
没有更新点。
第八次迭代,U=T、S={O、A、B、C、D、E、T}
从最短的O到T的没有更新点路径为13。
三,算法代码(C++实现)
#include<iostream>
#include<string>
using namespace std;
class Node{
public:
Node()
{
minL=100;//初始化最短路径为无穷大。
}
char node;//节点名称
int minL;//当前节点的最短路径
Node* last;//下一个节点
};//定义从一个节点类
void print(Node *node)//最短路径函数的递归打印
{
if (node == NULL)
{
return;
}
print(node->last);/*递归调用,先打印前面的节点*/
cout << node->node << "->";
}
int main()
{
int wvalue[8][8];//定义路径权重
for (int a = 0; a < 8; a++)
{
for (int b = 0; b < 8; b++)
{
wvalue[a][b] = 1000;//初始化权值,如若两个点没有连接则为无穷大。
}
}
wvalue[0][1] = 2;//根据图来设置各个点之间的路径。
wvalue[0][2] = 5;
wvalue[0][3] = 4;
wvalue[1][6] = 12;
wvalue[1][2] = 2;
wvalue[1][4] = 7;
wvalue[2][3] = 1;
wvalue[2][4] = 4;
wvalue[2][5] = 3;
wvalue[3][5] = 4;
wvalue[4][5] = 1;
wvalue[4][7] = 5;
wvalue[5][7] = 7;
wvalue[6][7] = 3;
Node node[8];//定义节点变量
node[0].node = 'O';//命名各个节点
node[0].last = NULL;//初始化前一个节点为空
node[1].node = 'A';
node[2].node = 'B';
node[3].node = 'C';
node[4].node = 'D';
node[5].node = 'E';
node[6].node = 'F';
node[7].node = 'T';
Node u;//定义当前被访问的节点
Node S[8];//辅助变量存储8个节点
int a = 0;
for (int i = 0; i < 8;i++) //第一个循环遍历这8个节点
{
u = node[i];//当前被遍历的节点
if (i==0)
{
u.minL = 0;//初始化第一个结点的最短路径
}
S[i] = node[i];//储存被遍历的节点
for (int j = 0;j<8; j++)//遍一个节点与其他8个节点的两个路径权值
{
if (u.minL + wvalue[i][j] < node[j].minL)/*如果当前节点的最短路径加上该节点到相邻节点的权重小于其下一个节点路径的权重,则更新其下一个节点路径的最小距离*/
{
node[j].minL = u.minL + wvalue[i][j];
node[j].last = &S[i];
}
}
}
cout << node[7].minL << endl;//打印最短路径
print(&node[7]);
return 0;
}
最后结果