数据结构与算法-100 days of learning-day3(欢迎批评指正)

方法1:直接将单源最短路算法调用|V|遍,对于稀疏图来说效果更好,时间复杂度T=
O( (|V| ^3)log|V| )。对于稠密图来说,该算法效率较低,时间复杂度为T = O( |V|^3 + |E||V|)。
方法2:Floyd算法
具体描述:
不管是有权图还是无权图,其初始矩阵均为邻接矩阵(一个图可以通过邻接矩阵来表示)。对于无权图来说,其邻接矩阵为对称矩阵。所以显然最终得到的每对顶点之间的最短路径和最短距离均为二维数组。这里用二维数组D来表示从顶点Vi到Vj的最短距离(D[i][j]),二维数组path表示从顶点Vi到Vj的最短路径(path[i][j])。
基本思想(此处从有权图出发,无权图类似):
如果找顶点Vi到Vj的最短路径,如果存在有向边直接或间接将这两个顶点相连,则它们之间存在一条长度为G[i][j](邻接矩阵)的路径。但这个路径不一定是最短路径,需要|V|次试探。
首先,观察图中路径<Vi,V0,Vj>是否存在。若存在,则比较<Vi,V0,Vj>与<Vi,Vj>这两者的路径长度并取短者,从而得到D0,也就是从Vi到Vj的途径顶点序号小于0的最短路径长度。
同理,在Vi到Vj的路径上再加入一个顶点V1,若<vi,…,v1>和<v1,…,vj>分别是“中间顶点的序号不大于0的最短路径”(也就是考虑完顶点V0后得到的矩阵D0,比如在该矩阵中的D[Vi][V1],D[V1][Vj]),且这两者路径长度之和与已经得到的从Vi到Vj的途径顶点序号小于0的最短路径长度进行比较,从而得到“中间顶点的序号不大于1的最短路径”,也就得到了<vi,…,v1,…,vj>的最短途径长度。
得到矩阵D1后,接着考察顶点V2,以此类推。经过|V|次比较,得到从顶点Vi到Vj的最短距离。根据如上分析,得到的一般规律如下:
在这里插入图片描述
具体例子:
如下图所示,给出了一个有权图并且用邻接矩阵表示出来。通过Floyd算法来得到每对顶点之间的最短路径以及最短路径长度。
在这里插入图片描述
图 8
这里同样是用二维数组D和path来分别表示每对顶点之间的最短路径长度和最短路径。
那么,根据前面的基本思想,我们需要对该矩阵进行|V|次试探。
首先,如图9所示,试探顶点V0,也就是考虑除了顶点V0之外其余两点之间的距离。所以说就是对应D-1矩阵中0行0列之外的非对角线元素,分别是D[1][2],D[2][1]。D[1][2]=2(所谓的<V1,V2>),再观察图中路径<V1,V0,V2>是否存在。发现存在,分别沿水平和垂直方向投影,得到D[1][0],D[0][2]。这两元素之和为17>2,所以D[1][2]保持不变。同理,D[2][1]=∞,这两点之间没有<V2,V1>,但存在<V2,V0,V1>这条路径。相较之下,得出D[2][1]被替换为7,所以说<V2,V1>的路径长度相较于以前是变小了。通过这个过程,D-1演变成D0。
接着,如图10所示,试探顶点V1。同样考虑除了顶点V1之外其余点之间的距离,分别为
在这里插入图片描述
图 9
在这里插入图片描述
图 10
在这里插入图片描述
图 11
D[0][2],D[2][0]。D[0][2]=11,该元素分别沿水平竖直两个方向对1行1列投影,得到D[0][1],D[1][2](分别对应<v0,v1>和<v1,v2>)。它们都是“中间顶点的序号不大于0的最短路径”,因为都是矩阵D0中的元素。这两段路径之和与已经得到的从V0到V2的途径顶点序号小于0的最短路径长度进行比较,即D0[0][2]=11>6=D0[0][1]+D0[1][2](也就是说1属于最短路径{ i→{ l≤1 }→j})。所以D1[0][2]=D0[0][1]+D0[1][2]更改为6(“中间顶点的序号不大于1的最短路径”)。同理,D[2][0]不需要更改(也就是说V1不属于最短路径{ 2→{ l≤1 }→0})。从而得到D1。
以此类推,如图11所示,考察顶点V2,得到D2。即得出每对顶点的最短路径的最终矩阵。
伪码描述:
在这里插入图片描述
如上图所示,对于Floyd算法的第一个嵌套循环是为了初始化二维数组D和path,它们分别是用来表示Vi到Vj的最短路径长度和最短路径。path[i][j] = -1表示这两个顶点之间是没有路径的。
对于第二个嵌套循环来说,最外层循环是与矩阵D的上标k相关。所以说就是不断得出D0,D1,……,D|V|-1。接着的内层循环是分别与i,j相关,也就是要检查每一个D矩阵中的每一个元素的值是否达到最短路径长度的要求。也就是说,不满足if语句条件则不发生变化。否则最短路径将发生更改。Path[i][j] = k表示从顶点Vi到Vj的最短路径中,Vk为中间顶点:ViVkVj。由此可以递归打印出这两点之间的最短路径。
时间复杂度为关于|V|的多项式。其中最高阶为3,所以T = O( |V|3 )。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值