关于
Kruskal
算法的一点想法
首先是
cut property
,对于两个互不相交的,也没有边
cross
这两个子集,如果在这两个子集的两个节点之间找条权重最轻的边,则符合最小生成树的过程。
伪代码:
Procedure kruskal
(
G,w
)
Input
:
A connected undirected graph G=(V
,
E) with edges weights w e
Output
:
A minimum spannning tree defined by the edges X
for all u
∈
V
:
Makeset
(
u
)
sort the edges E by weight
for all edges {u
,
v}
∈
E,in increasing order of weight
if find
(
u
)!
=find
(
V
)
add edge{u
,
v} to X
union
(
u
,
v
)
makeset
函数将每一个节点分成一个集合,在节点的结构里加一个
parent
的
Vnode
指针,
makeset
的时候就将
parent
指向子集,加一个
rank
的
int
来表示层数,初始化时为
0
;
对边进行排序的时候可以构造个边类型,里面包括起始节点和结尾节点。
Find
函数就是不断访问
u
的父节点知道最高层,如果相等不做任何操作,当最高层不相等的时候将
u
,
v
对应的边加入到最后的最小生成树的结构体中。将两个集合合并成一个集合,即判断父节点
rank
的值,小的一方加到大的一方,即小的一方的最高节点的父节点指向到大的一方的最高节点上,然后将
rank
的值增加
1.
优化:
在
find
的时候就将不是最终节点的值,可以一边找的之后一边将边直接指向父节点的父节点。
优化的find函数的伪代码如下:
function find(x)
if x!=parent(x) parent(x)=find(parent(x))
return parent(x)