我正在实现 Kruskal 算法,这是一种众所周知的查找加权图的最小生成树的方法。但是,我正在对其进行调整以在图中查找循环。这是 Kruskal 算法的伪代码:
KRUSKAL(G):
1 A = ∅
2 foreach v ∈ G.V:
3 MAKE-SET(v)
4 foreach (u, v) ordered by weight(u, v), increasing:
5 if FIND-SET(u) ≠ FIND-SET(v):
6 A = A ∪ {(u, v)}
7 UNION(u, v)
8 return A
我很难掌握FIND-SET()
andMAKE-SET()
函数,或者它们在不相交集数据结构中的实现。
我当前的代码如下所示:
class edge {
public: //for quick access (temp)
char leftV;
char rightV;
int weight;
};
std::vector<edge> kruskalMST(std::vector<edge> edgeList){
std::vector<char> set;
std::vector<edge> result;
sortList(edgeList); //sorts according to weight ( passed by reference)
do{
if(set.empty()){
set.push_pack(edgeList[i].leftV); //also only push them when
set.push_pack(edgeList[i].rightV); //they aren't there , will fix
result.push_back(edgeList[i]);
++i;
}
else {
if((setContains(set , edgeList[i].leftV)) && (setContains(set , edgeList[i].rightV)))
++i; //skip node
else {
set.push_pack(edgeList[i].leftV); //also only push them when
set.push_pack(edgeList[i].rightV); //they aren't there , will fix
result.push_back(edgeList[i]);
++i;
}
} while(i<edgeList.size());
return result;
}
当已经存在的两个顶点set vector
再次出现时,我的代码在图中检测到一个循环。在我遇到这样的情况之前,这似乎在大多数情况下都有效:
[a] [c]
| |
| |
| |
[b] [d]
当这些边按排序顺序出现时,会发生这种情况,因为a
, b
, c
,d
已经被推入set vector
. 加入[a]
到[c]
不会在图中产生循环,但由于当前实现而被检测为循环。
在我的情况下,是否有任何可行的替代方法来检测周期?或者,如果有人可以解释Kruskal 算法的MAKE-SET
、FIND-SET
和UNION
工作原理,那将有很大帮助。