图的相关算法:Prim&Kruskal&Dijstradj&Floyd算法

本文深入解析了最小生成树算法,包括普里姆算法的边选择策略,克鲁斯卡尔算法的简单性,以及Dijkstra算法如何从局部最优扩展到全局最短路径。探讨了Dijkstra算法的贪心策略正确性的关键原理。同时,介绍了Floyd算法用于计算所有顶点间最短距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最小生成树

普里姆(Prim)算法

找出与当前生成树相邻最小的边(不会构成回路:因为是只有生成树内部点相连才会构成回路,而算法选择的是当前生成树到为并入点的最小距离)

克鲁斯卡尔(Kruskal)算法

直接选取权值最小的(不构成回路:并查集)
并查集

Dijkstra算法成立的前提条件是不存在负权的边
所以 最短路径在不存在负边的前提下,有"渔网"的物理解法(真的是现实世界的降维打击)

Dijkstra算法:计算某个源点到其他点的最短距离

与当前的点集相邻的最短距离
对普里姆(Prim)算法稍加改动既是Dijkstra 算法,(二者十分类似,只不过在求最短距离时prim面对的是所有的点集,而Dijstra面对的是源点v0,所以有了距离逐步累加的过程)

源点到任意一个点的最短距离,要么是源点到它的某条边的长度,要么是源点到另一个点的最短距离距离,再加上另一个点到这个点的边的长度

在这里插入图片描述

已经并入的节点未并入dist[]path[]备注
vo未并入{+,100,50,10*,+}{-1,0,0,0,-1}并入v3
v0,v3(并入v3后)未并入{+,100,50*,10,90}{-1,0,0,0,3}并入v2
v0,v3,v2未并入{+,100,50,10,90*}{-1,0,0,0,3}并入v4
v0,v3,v2,v4未并入{+,100*,50,10,90}{-1,0,0,0,3}并入v1
v0,v3,v2,v4,v1未并入{+,100*,50,10,90}{-1,0,0,0,3}并入v1

dijstra算法的贪心为什么是正确的?

Dijkstra算法的贪心策略是基于局部最优解,即从起点到当前节点的最短路径,然后通过不断更新节点的距离来求出整个图的最短路径。这种贪心策略的正确性基于以下两个事实:

  1. 局部最优解是全局最优解的一个组成部分:在Dijkstra算法中,每次都选择距离起点最近的节点作为下一个处理的节点,这个节点的距离就是从起点到该节点的最短距离,因此这个局部最优解一定是全局最优解的一个组成部分。

  2. 没有更优的路径可以到达某个节点:一旦一个节点的距离被确定,就不可能有更短的路径可以到达该节点,因为如果存在更短的路径,那么这个节点的距离就会被更新成更短的距离,这个事实也保证了局部最优解一定是全局最优解的一个组成部分。

因此,Dijkstra算法的贪心策略是正确的。

Floyd算法:计算每一对顶点间的最短距离


function floyd(arr,path) {
let i,j,v;

for(v=0;v<n;v++)/*对于某个中枢节点*/
   for(i=0;i<n;i++)
     for(j=0;j<n;j++)
         if(arr[i][j]>arr[i][v]+arr[v][j]){arr[i][j]=arr[i][v]+arr[v][j];path[i][j]=v;}

}
var path=[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]];
var a=[[0,5,1000,7],[1000,0,4,2],[3,3,0,2],[1000,1000,1,0]];
floyd(a,path);
console.log(a);
console.log(path);

function printpath(qi,zhi,path) {
   if(path[qi][zhi]==-1){console.log("链接"+qi+"-->"+zhi);}
   else
   {
    var mid=path[qi][zhi];//中间点
    printpath(qi,mid,path);//分而治之
    printpath(mid,zhi,path);//分而治之
   }
}
printpath(1,2,path);



在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值