这里使用的是Dijkstra来计算最短路径。事实上Dijkstra完成时,指定节点到所有节点的最小路径均已求出。
算法简述如下:
准备好两个辅助性数据结构:
1 ParentLength : 用来记录到当前节点之前的父节点,与到当前节点的最小路径
2 Path: 记录指定节点到所有节点的ParentLength。初始化时,所有的ParentLength的父节点都为指定的起始节点,长度都是INFINITY,代表没有联通,距离无穷大。
Path的关键算法是adjust(from,to,length),每当发现一条新的,从一个已访问的节点(from)到未访问的节点(to)之间的新路径时,Path则用其更新ParentLength列表,重新计算到那个未访问节点(to)的最新距离:以前到from节点的距离+新的距离,然后比较它与to节点对应的ParentLength老的距离之间的长度,如果新距离短,则将to节点对应的ParentLength更新为长度为新距离的,父节点为from;以此步骤保证Path总是保持当前遍历状态下,到各个节点的最短路径。
Path的另一个关键算法是getMin,它会返回到所有未访问节点中,最短的路径的那个节点。
图使用邻接矩阵法表示,关于邻接矩阵可参见:Graph 图-邻接表法
Graph.path是最小路径算法,工作方式如下:
根据指定的起始节点初始化返回值Path对象。
将指定的起始节点标志为已访问。并设置为当前节点。
然后
1 找到当前节点所有联通的未知节点,和到这些路径长度,调用Path.adjust更新Path。
2 步骤 1 结束后,从调用Path.getMin获得到所有未访问节点中,最短的路径的那个节点。标志为访问过,并作为当前节点。
3 重复 步骤 1 步骤 2 n次(n为图中的节点数量),算法结束。
代码中的Path.print()为打印函数,为测试之用。
Path.main()提供简单测试。
1
classParentLength
{//记载上一个节点与当前最小路径2
privateintparent;//上一个节点3
privateintlength;//最小路径长度4
ParentLength(intparent,intlength)
{5
this.parent=parent;6
this.length=length;7
}8
9
intparent()
{returnparent; }10
intlength()
{returnlength; }11
}12
13
classPath
{//存储最小路径14
privateParentLength[] pls;15
privateGraph g;//确定指定位置的节点是否被访问过和打印时使用16
Path(intsize,intstart, Graph g)
{17
//初始化最小路径数组,将所有最小路径的起点都置为start,并将路径长度置为INFINITY18
pls=newParentLength[size];19
for(inti=0; i pls[i]=newParentLength(start,Graph.INFINITY);21
this.g=g;22