编程语言
首页 > 编程语言> > 克鲁斯卡尔(Kruskal)算法

克鲁斯卡尔(Kruskal)算法

作者:互联网

概览

 

相比于普里姆算法(Prim算法),克鲁斯卡尔算法直接以边为目标去构建最小生成树。从按权值由小到大排好序的边集合{E}中逐个寻找权值最小的边来构建最小生成树,只要构建时,不会形成环路即可保证当边集合{E}中的边都被尝试了过后所形成的树为最小生成树。

 

定义

 

假设G=(V, {E})是连通网(即带权连通图),则令最小生成树的初始状态为只有N个顶点而无边的非连通图T=(V, {}),图T中每个顶点自成一个连通分量。在图G的边集{E}中选择权值最小的边e,若e依附的顶点落在T中不同的连通分量上,则将e加入到T中,否则舍去e而选择下一条权值最小的边。以此类推,直至T中所有顶点都在同一连通分量上为止。

 

相关概念

 

连通:在无向图G中,如果从顶点v到v’有路径,则称v和v’是连通的。

连通图:如果对于图G中任意两个顶点vi、vj∈E,vi和vj都是连通的,则称G是连通图。

 

过程简述

 

输入:带权连通图(网)G的边集E及顶点个数。(E已按权值的升序排序。)

 

初始:T=(V, {}), V是图G的顶点集合且各顶点自成一个连通分量;表示边的集合为空{}。

 

操作:重复以下操作,直到T中所有顶点都在同一个连通分量上。

 

输出:最小生成树。

 

如何实现

 

输入:用Edge类表示边,其中Begin/End/Weight域分别表示边的两个顶点的下标及权重。Edge数组E表示边集,N表示顶点个数。(E已按权值的升序排序。)

 

初始:用包含N个存储单元的数组parent表示T=(V, {})的 V,即各顶点自成的连通分量。parent数组的下标i即为顶点的下标,i处存放的值parent[i]即为连通分量中下一个顶点的下标,parent[i]=0表示该连通分量已结束。将parent的各存储单元初始化为0。

 

操作:重复以下操作,直到T中所有顶点都在同一个连通分量上。

 

输出:最小生成树。

 

如上面的这个图G=(V, {E}),其中V={v0, v1, v2, v3, v4, v5, v6, v7, v8},E= {(v4, v7, 7), (v2, v8, 8), (v0, v1, 10), (v0, v5, 11), (v1, v8, 12), (v3, v7, 16), (v1, v6, 16), (v5, v6, 17), (v1, v2, 18), (v6, v7, 19), (v3, v4, 20), (v3, v8, 21), (v2, v3, 22), (v3,v6, 24), (v4, v5, 26)}

 

用一个边集来表示该图G,得上图右边的数组。

 

① 输入:带权连通图G=(V, {E})的边集合及顶点数目,求图G的最小生成树。

② 初始:T={V, {}},用数组parent=int[9]来表示V,parent数组记录的是以索引i表示的顶点开始到parent[i]表示的顶点构成的连通图。例如:(parent数组本身就含有两个信息:索引和索引处的值,vertex数组是不存在的,只是为了辅助理解。)

非连通图头顶点下标vertex:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标parent:[ 0, 0, 8, 0, 7, 0, 0, 0, 0 ]

parent[2]=8,parent[8]=0即顶点v2、v8构成一个连通分量。

parent[4]=7,parent[7]=0即顶点v4、v7构成一个连通分量。

③ 操作:

 

1.上图中,边(4, 7, 7)权值最小,取该边为e。

 

2. 此时parent[4]=0,故n=4;parent[7]=0,故m=7;n≠m故parent[4]=7,将{v4}和{v7}这两个连通图合并为一个连通图。执行后parent数组如下:

非连通图头顶点下标vertex:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标parent:[ 0, 0, 0, 0, 7, 0, 0, 0, 0 ]

 

解释:parent[2]=0,即v2自成一个连通图。parent[4]=7,parent[7]=0即v4所在连通图中还有v7,v7接下来没有别的顶点了,即v4、v7在同一个连通图中。

3.从E中取下一条边继续上面1、2步骤的操作。

 

④输出:

 

演示过程

 

(4,7) = 7

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 0, 0, 0, 0, 7, 0, 0, 0, 0 ]

(2,8) = 8

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 0, 0, 8, 0, 7, 0, 0, 0, 0 ]

(0,1) = 10

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 0, 8, 0, 7, 0, 0, 0, 0 ]

(0,5) = 11

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 5, 8, 0, 7, 0, 0, 0, 0 ]

(1,8) = 12

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 5, 8, 0, 7, 8, 0, 0, 0 ]

(3,7) = 16

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 5, 8, 7, 7, 8, 0, 0, 0 ]

(1,6) = 16

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 5, 8, 7, 7, 8, 0, 0, 6 ]

(6,7) = 19

非连通图头顶点下标:[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

非连通图尾顶点下标:[ 1, 5, 8, 7, 7, 8, 7, 0, 6 ]

 

运行结果

 

(4, 7) = 7

(2, 8) = 8

(0, 1) = 10

(0, 5) = 11

(1, 8) = 12

(3, 7) = 16

(1, 6) = 16

(6, 7) = 19

 

算法代码

 

见链接:克鲁斯卡尔(Kruskal)算法(代码) - kokiafan - 博客园 (cnblogs.com)

 

复杂度

 

它的时间复杂度为O(eloge)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树。

 

参考资料:

《大话数据结构》 - 程杰 著 - 清华大学出版社 第252页

标签:连通,下标,parent,Kruskal,克鲁斯,算法,数组,顶点,分量
来源: https://www.cnblogs.com/kokiafan/p/14777439.html