一、什么是克鲁斯卡尔?
克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树.
二、原理
克鲁斯卡尔算法的思想是站在了上帝视角.先把权值最短的边一个个挑出来,然后判断挑出来的边是否构成环,如果不构成环则是最小生成树的一部分,否则边过滤
三、代码实现
/**
* 最小生成树
* 克鲁斯卡尔算法
*/
public class Test {
/**
* 所有边集合
*/
private static final List<Edges> EDGES_LIST;
private static final List<Integer> PARENT;
static {
Edges edges0 = new Edges(4, 7, 7);
Edges edges1 = new Edges(2, 8, 8);
Edges edges2 = new Edges(0, 1, 10);
Edges edges3 = new Edges(0, 5, 11);
Edges edges4 = new Edges(1, 8, 12);
Edges edges5 = new Edges(3, 7, 16);
Edges edges6 = new Edges(1, 6, 16);
Edges edges7 = new Edges(5, 6, 17);
Edges edges8 = new Edges(1, 2, 18);
Edges edges9 = new Edges(6, 7, 19);
Edges edges10 = new Edges(3, 4, 20);
Edges edges11 = new Edges(3, 8, 21);
Edges edges12 = new Edges(2, 3, 22);
Edges edges13 = new Edges(3, 6, 24);
Edges edges14 = new Edges(4, 5, 26);
EDGES_LIST = Arrays.asList(edges0, edges1, edges2, edges3, edges4, edges5, edges6, edges7, edges8, edges9, edges10, edges11, edges12, edges13, edges14);
PARENT = new ArrayList<>(EDGES_LIST.size());
for (int i = 0; i < EDGES_LIST.size(); i++) {
PARENT.add(0);
}
}
public static void main(String[] args) {
for (Edges edges : EDGES_LIST) {
int begin = find(edges.getBegin());
int end = find(edges.getEnd());
// 如果begin == end 说明已经成环 ,成环的edges边不能要
if (begin != end) {
System.out.println("路径:" + edges.getBegin() + "-" + edges.getEnd() + " 权值:" + edges.getWeight());
PARENT.set(end, begin);
}
}
}
/**
* 查找当前节点的起始节点
*
* @param index
* @return
*/
private static int find(int index) {
while (PARENT.get(index) > 0) {
index = PARENT.get(index);
}
return index;
}
}
class Edges implements Comparable<Edges> {
/**
* 起始点
*/
private int begin;
/**
* 终点
*/
private int end;
/**
* 权值
*/
private int weight;
public int getBegin() {
return begin;
}
public void setBegin(int begin) {
this.begin = begin;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Edges(int begin, int end, int weight) {
this.begin = begin;
this.end = end;
this.weight = weight;
}
@Override
public int compareTo(Edges o1) {
return this.weight > o1.weight ? 1 : -1;
}
}