import java.util.Arrays;
/**
* @author Drug
* @create 2020-05-16 12:01
*/
public class Kurskal {
//边数
private int edgeNum;
//顶点信息
private char[] vertexs;
//权值矩阵
private int[][] matrix;
//表示无法连通的最大值
private static final int INF = Integer.MAX_VALUE;
public static void main(String[] args) {
char[] vertexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
//克鲁斯卡尔算法的邻接矩阵
int[][] matrix = {
/*A*//*B*//*C*//*D*//*E*//*F*//*G*/
/*A*/ {0, 12, INF, INF, INF, 16, 14},
/*B*/ {12, 0, 10, INF, INF, 7, INF},
/*C*/ {INF, 10, 0, 3, 5, 6, INF},
/*D*/ {INF, INF, 3, 0, 4, INF, INF},
/*E*/ {INF, INF, 5, 4, 0, 2, 8},
/*F*/ {16, 7, 6, INF, 2, 0, 9},
/*G*/ {14, INF, INF, INF, 8, 9, 0}};
//大家可以在去测试其它的邻接矩阵,结果都可以得到最小生成树.
//Kurskal 对象实例
Kurskal kurskal = new Kurskal(vertexs, matrix);
//输出构建的
kurskal.print();
EData[] eData = kurskal.getEData();
System.out.println(Arrays.toString(eData));
System.out.println("克鲁斯卡尔法求最小生成树后:");;
kurskal.kruskal();
}
/**
* 构造
*
* @param nVertexs
* @param nMatrix
*/
public Kurskal(char[] nVertexs, int[][] nMatrix) {
vertexs = new char[nVertexs.length];
//顶点信息赋值
for (int i = 0; i < nVertexs.length; i++) {
vertexs[i] = nVertexs[i];
}
//边信息赋值
matrix = new int[nMatrix.length][nMatrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[i][j] = nMatrix[i][j];
if (matrix[i][j] != INF && i > j) {
edgeNum++;
}
}
}
}
/**
* 打印输出
*/
public void print() {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
System.out.printf("%12d", matrix[i][j]);
}
System.out.println();
}
}
/**
* 按照边权值排序
*
* @param edges
*/
private void sortEdges(EData[] edges) {
for (int i = 0; i < edges.length - 1; i++) {
for (int j = 0; j < edges.length - 1 - i; j++) {
if (edges[j].weight > edges[j + 1].weight) {
EData temp = edges[j];
edges[j] = edges[j + 1];
edges[j + 1] = temp;
}
}
}
}
/**
* 返回顶点下标
*
* @param c
* @return
*/
private int getPosition(char c) {
for (int i = 0; i < vertexs.length; i++) {
if (vertexs[i] == c) {
return i;
}
}
//没有找到
return -1;
}
/**
* 返回边信息
* @return
*/
private EData[] getEData() {
//计算器
int index = 0;
//初始化
EData[] edges = new EData[edgeNum];
//赋值
for(int i=0;i<matrix.length;i++){
for(int j=i+1;j<matrix[0].length;j++){
if(matrix[i][j] != INF){
edges[index++] = new EData(vertexs[i],vertexs[j],matrix[i][j]);
}
}
}
return edges;
}
/**
* 返回顶点i对应的终点信息
* @param ends
* @param i
* @return
*/
private int getEnd(int[] ends, int i) {
//如果end[i]等于0,说明没有指向,即返回本身
//如果不等于0,说明有指向,返回指向节点
while(ends[i] != 0) {
i = ends[i];
}
return i;
}
private void kruskal(){
//计数器
int index = 0;
//各边的终点
int[] end = new int[edgeNum];
//结果集,n个顶点 n-1条边
EData[] res = new EData[vertexs.length-1];
//获得边信息
EData[] edges = getEData();
//排序边信息
sortEdges(edges);
//开始依次判断
for(int i=0;i<edgeNum;i++){
//一个顶点
int p1 = getPosition(edges[i].start);
//另一个顶点
int p2 = getPosition(edges[i].end);
//获得p1终点信息
int end1 = getEnd(end, p1);
//获得p2终点信息
int end2 = getEnd(end, p2);
//如果两点不构成回路
if(end1 != end2){
//终点信息变更
end[end1] = end2;
//结果加入数组
res[index++] = edges[i];
}
}
System.out.println(Arrays.toString(res));
}
}
class EData {
/**
* 一个端点
*/
char start;
/**
* 另一个端点
*/
char end;
/**
* 权值
*/
int weight;
public EData(char start, char end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
@Override
public String toString() {
return "EData{" +
"<" + start +
", " + end +
"> " + weight +
'}';
}
}
java克鲁斯卡尔(kruskal)最小生成树代码实现
最新推荐文章于 2024-04-02 04:11:00 发布