数据结构之图:最小生成树算法详解与Java实现(Kruskal算法与Prim算法)

本文详细介绍了Kruskal算法和Prim算法,用于解决图的最小生成树问题。Kruskal算法利用并查集,按边权值升序选取边,避免形成环。Prim算法则通过优先级队列(或数组),每次选择与树最近的节点加入。文章包括算法思想、步骤、伪代码、图解及Java代码实现,同时分析了两种算法的时间复杂度。
摘要由CSDN通过智能技术生成

一、Kruskal算法

1.算法思想

设有两颗树 A , B A,B A,B,需要从中选取两个结点相连。
情况1:选取的结点 u , v u,v u,v属于同一颗树,则 u , v u,v u,v的连接必然使得那棵树形成回路,此时 A , B A,B A,B无论如何都不能再组成一颗树。
情况2:选取的结点 u , v u,v u,v分属于 A , B A,B A,B,则 u , v u,v u,v的连接不会构成回路,此时 A , B A,B A,B已然组成一颗新树 C C C
为了使得新树 C C C的总权值最小,需要使得 w = m i n { w e i g h t ( u , v ) , u ∈ A . V , v ∈ B . V } w=min \begin{Bmatrix}weight_{(u,v)},u\in A.V,v\in B.V \\ \end{Bmatrix} w=min{ weight(u,v),uA.V,vB.V};否则,必然可以构造出一个 A , B A,B A,B结合的总代价更小的生成树。

现将一个图中所有的 n n n个结点均看作一颗独立的只有根结点的树,从中可以选取一条权值最小的边来将某两颗树合并为一颗新树。按照上面的思想,需要判断该边连接的结点 u , v u,v u,v是否属于同一颗树,否则将有构成回路的风险。因此,每次取出所有边中权值最小的边 w w w,判断连接的结点 u , v u,v u,v是否是同一颗树,若是则不作考虑;若否则将两棵树合并为一棵树并将 u , w , v u,w,v u,w,v加入到结果集中,表示该边为最小生成树的一条边。直至边被取完。

2.算法步骤

S t e p 1 : Step 1: Step1结果集置空
S t e p 2 : Step 2: Step2将所有结点看作一颗只有一个元素的集合
S t e p 3 : Step 3: Step3其次将所有边按照权值大小升序排列
S t e p 4 : Step 4: Step4遍历已经排序好的边:1)如果边连接的两个结点在同一集合中,则不做任何操作;2)如果边连接的两个结点 u , v u,v u,v不在同一个集合中,则将这两个结点所在的集合合并为一个集合,并将 u , v u,v u,v加入结果集中
S t e p 5 : Step 5: Step5返回结果

3.伪代码(参考自算法导论)

用到了并查集这一结构:并查集原理与实现
K r u s k a l ( G ) Kruskal(G) Kruskal(G)
1. A = ∅ 1.A=\varnothing 1.A=
2. f o r 2.for 2.for v ∈ G . V v \in G.V vG.V
M A K E − S E T ( v ) MAKE-SET(v) MAKESET(v)
3. e L i s t ← s o r t ( e ∈ G . E ) 3.eList\leftarrow sort(e \in G.E) 3.eListsort(eG.E) / / o r d e r //order //order b y by by w e i g h t weight weight
4. f o r 4.for 4.for e ∈ e L i s t e \in eList eeList
i f if if F I N D − S E T ( u ) ≠ F I N D − S E T ( v ) FIND-SET(u)\ne FIND-SET(v) FINDSET(u)=FINDSET(v)
   A = A ∪ ( u , v ) A=A\cup (u,v) A=A(u,v)
   U N I O N ( u , v ) UNION(u,v) UNI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值