前言
本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。
Kruskal算法(Kruskal的实现原理)
Kruskal算法的原理:
就是每次取最小的边,看看是不是与已经选择的构成回路,不构成回路,就加进来,继续,直到选了N-1条边。
对于判断回路来说,BFS和DFS应该是都可以的(类似于判断连通分量),但是,之前已经写过BFS和DFS代码了,所以在这里用并查集实现(当然,博主自己没试过DFS和BFS,感兴趣的可以自己去试一试)。
还是这个图,底下的是使用排序排好序的EData类。
Kruskal 的实现代码
首先,我们可以把排序的代码单拎出来
//用于对之前定义的to进行排序
public void toSort(){
Collections.sort(this.to, new Comparator<EData>() {
@Override
public int compare(EData o1, EData o2) {
//顺序对就是升序,顺序不对就是降序,比如我现在是o1和o2传进来,比较时候o1在前就是升序,o1在后就是降序
int result = Integer.compare(o1.weight,o2.weight);
return result;
}
});
}
之后因为要用到并查集,我们把并查集的基本代码拎出来
//并查集查找
public int find(int x,int[] f){
while(x!=f[x]){
x = f[x];
}
return x;
}
//并查集合并
public int union(int x,int y,int[] f){
find(x,f);
find(y,f);
if(x!=y){
f[x] = y;
return y;
}
return -1; //如果一样的集合就返回-1
}
之后就来首先Kruskal,注意最后返回的是一个ArrayList,为了方便看选的哪条边,我就直接把两头都加进去了,有需要的话,自行更改代码即可
public ArrayList<Integer> kruskal(){
//kruskal是对form to weight这种结构的类进行排序,然后选取最短的一条边,看是否形成回路,加入
toSort(); //调用toSort进行排序
//由于要判断是否形成回路,我们在这用并查集
//初始化并查集
int[] f = new int[vertexList.size()];
for(int i = 0;i<vertexList.size();i++){
f[i] = i;
}
ArrayList<Integer> res = new ArrayList<>();
int count = 0;
for(int i = 0;count != vertexList.size()-1 && i<this.to.size();i++){
//之后就是开始取边了
EData temp = this.to.get(i);