1.主要思想
和Prim算法不同,克鲁斯卡尔算法是依次遍历图中的边,按照边的权值进行构造最小生成树,关键是要判断每次加入的边和已经加入的边是否构成回路(这是关键),最后生成了一个有(vertex-1)条边的最小生成树。
2.代码实现
1.克鲁斯卡尔类
package KruskalAlgothm;
import javax.swing.*;
import java.util.Arrays;
public class Kruskal {
private int edgeNum;
private char[] vertex;
private int[][] Link_Array;
private static int Max = Integer.MAX_VALUE;
public Kruskal() {
}
public Kruskal(char[] vertexs, int[][] Link_Array) {
this.vertex = new char[vertexs.length];
for (int i = 0; i < vertexs.length; i++) {
this.vertex[i] = vertexs[i];
}
this.Link_Array = new int[vertex.length][vertex.length];
for (int i = 0; i < vertex.length; i++) {
for (int j = 0; j < vertex.length; j++) {
this.Link_Array[i][j] = Link_Array[i][j];
}
}
for (int i = 0; i < vertex.length; i++) {
for (int j = 0; j < vertex.length; j++) {
if (this.Link_Array[i][j] != Max) {
edgeNum++;
}
}
}
}
public void print_LinkArray() {
System.out.println("邻接矩阵为:");
for (int row = 0; row < vertex.length; row++) {
for (int line = 0; line < vertex.length; line++) {
System.out.printf("%12d", Link_Array[row][line]);
}
System.out.println();
}
}
public void SortEdge(Edge[] edges) {
for (int i = 0; i < edgeNum - 1; i++) {
for (int j = 0; j < edgeNum - 1 - i; j++) {
if (edges[j].value > edges[j + 1].value) {
Edge temp = edges[j + 1];
edges[j + 1] = edges[j];
edges[j] = temp;
}
}
}
}
public int getVertex_Index(char v) {
for (int i = 0; i < vertex.length; i++) {
if (vertex[i] == v) {
return i;
}
}
return -1;
}
public Edge[] getEdge() {
int index = 0;
Edge[] edges = new Edge[edgeNum];
for (int i = 0; i < vertex.length; i++) {
for (int j = 0; j < vertex.length; j++) {
if (Link_Array[i][j] != Max) {
edges[index++] = new Edge(vertex[i], vertex[j], Link_Array[i][j]);
}
}
}
return edges;
}
public int getEnd(int[] vertex, int index) {
while (vertex[index] != 0) {
index = vertex[index];
}
return index;
}
public void KruskalAlgothm() {
int index = 0;
int[] ends = new int[edgeNum];
Edge[] result = new Edge[edgeNum];
Edge[] edges = getEdge();
SortEdge(edges);
for (int i = 0; i < edgeNum; i++) {
int vertex_start = getVertex_Index(edges[i].start);
int vertex_end = getVertex_Index(edges[i].end);
int m = getEnd(ends, vertex_start);
int n = getEnd(ends, vertex_end);
if (m != n) {
ends[m] = n;
result[index++] = edges[i];
}
}
System.out.println("最小生成树为:");
for (int i = 0; i < index; i++) {
System.out.println(result[i]);
}
}
}
2.边
package KruskalAlgothm;
public class Edge {
char start;
char end;
int value;
public Edge() {
}
public Edge(char start, char end, int value) {
this.start = start;
this.end = end;
this.value = value;
}
@Override
public String toString() {
return
"<" + start + "," + end + ":" + value + '>';
}
}
3.入口
package KruskalAlgothm;
import java.util.Arrays;
public class Input {
static int Max = Integer.MAX_VALUE;
public static void main(String[] args) {
char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int[][] Link_Array = {
{0, 12, Max, Max, Max, 16, 14},
{12, 0, 10, Max, Max, 7, Max},
{Max, 10, 0, 3, 5, 6, Max},
{Max, Max, 3, 0, 4, Max, Max},
{Max, Max, 5, 4, 0, 2, 8},
{16, 7, 6, Max, 2, 0, 9},
{14, Max, Max, Max, 8, 9, 0}
};
Kruskal kruskal = new Kruskal(vertex, Link_Array);
kruskal.print_LinkArray();
System.out.println("存放边的数组:");
Edge[] edges = kruskal.getEdge();
System.out.println("排序前:" + Arrays.toString(edges));
kruskal.SortEdge(edges);
System.out.println("排序后:" + Arrays.toString(edges));
kruskal.KruskalAlgothm();
}
}