Kruskal算法(克鲁斯卡尔算法)

Kruskal算法是一种寻找最小生成树的贪心算法,由Joseph Kruskal于1956年提出。该算法首先构建只含顶点的子图,然后按权值从小到大选取边,如果边的两端点不在同一棵树上则添加,直至形成一个连通的子图,即最小生成树。执行步骤包括边的排序、判断和连接,适合于边相对较少的图。与Prim算法相比,Kruskal更适用于稀疏图。

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

Kruskal算法

Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。

概念解释

Kruskal算法定义:**先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有 n-1 条边为止。

最小生成树定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。(可以由Kruskal算法或者prim算法求出来)

执行步骤:
第一步:在带权连通图中,将边的权值排序;
第二步:判断是否需要选择这条边(此时图中的边已按权值从小到大排好序)。判断的依据是边的两个顶点是否已连通,如果连通则继续下一条;如果不连通,那么就选择使其连通。
第三步:循环第二步,直到图中所有的顶点都在同一个连通分量中,即得到最小生成树。

图解Kruskal算法

[外链图片转存失败(img-SMyVUx2V-1562946282066)(img/1.png)]

首先将图中的所有的边按权值从小到大排序:
HG < (CI=GF) < (AB=CF) < GI < (CD=HI) < (AH=BC) < DE < BH < DF
接着,我们选择HG这条边,这样就将H和G这两个点加入到了已经找到的点的集合。如下图所示:

[外链图片转存失败(img-uZ2FLyHQ-1562946282068)(img/3.png)]

由于两个一样的权值的边存在,所以就可以随便选一条,但是需要做出判断。
判断的法则:
(1)当所选的边加入已找到边的集合时候,会不会形成回路。如果没有形成回路,那么就“准备”将其连通,在真正连通之前还需要做一次判断,判断这两个点是否已经加入到已找到点的集合中去了
(2)如果两个点都没有出现,则将这两个点都加入到集合中去
(3)如果其中有一个点已经出现在集合中,则将另一个没有出现过的点,加入到集合中去
(4)如果两个都有出现,则不需要加入。

[外链图片转存失败(img-RpZmzgTZ-1562946282070)(img/2.png)]

[外链图片转存失败(img-D3tpD4SM-1562946282074)(img/4.png)]

[外链图片转存失败(img-YpGFm3bz-1562946282076)(img/5.png)]

以上三步不会形成回路,所以可以直接连通。

[外链图片转存失败(img-c8DwVRU9-1562946282079)(img/6.png)]

在连接IG的时候,会形成回路,所以放弃连通。
如何判断的?注意听这里是算法实现的重点:
判断两个已经连接到第三个点的点,会不会连接。

[外链图片转存失败(img-L9NUaVwQ-1562946282080)(img/7.png)]

[外链图片转存失败(img-7HVtpbrO-1562946282095)(img/8.png)]

至此我们得到了一个最小生成树。所有的点都在一个连通分量上了。

注意点:排序和防止回路

排序的解决:很好解决

(1)、只能用图中有的边;
(2)、只能用掉|v|-1条边;
(3)、不能有回路。

kruskal和prim的比较:

kruskal适用于比较稀疏的图,因为他每次都是从最小的边开始查找。让森林合并为树

prim算法适用于变数比较多的图。让小树慢慢长大。

简单的例子:

[外链图片转存失败(img-68olnHfZ-1562946282096)(img/9.png)]

public class Kruskal2 {
   
   

    private Edge[] edges;
    private int edgeSize;

    public Kruskal2(int edgeSize) {
   
   
        this
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值