package com.gxmedu.kruskal;
/**
* @author 郭学明
* @version 1.0
* 边的值 >0,若为0,则为本身。
*/
public class MGraph {
public static void main(String[] args) {
char[] data = new char[]{'A','B','C','D','E','F','G'};
int[][] weight = new int[][]{
{0,12,INF,INF,INF,16,14},
{12,0,10,INF,INF,7,INF},
{INF,10,0,3,5,6,INF},
{INF,INF,3,0,4,INF,INF},
{INF,INF,5,4,0,2,8},
{16,7,6,INF,2,0,9},
{14,INF,INF,INF,8,9,0}
};
MGraph mGraph = new MGraph(data, weight);
mGraph.kruskal();
}
private static final int INF = Integer.MAX_VALUE;
int vertexNum;
int edgeNum;
char[] data;
// 邻接矩阵
int[][] edgesWeight;
Edge[] edges;
// int[] destination;
public MGraph(char[] data, int[][] edgesWeight){
vertexNum = data.length;
this.data = new char[data.length];
this.edgesWeight = new int[vertexNum][vertexNum];
// this.edges = new Edge[vertexNum];
// 不会对原数组的数据造成影响
for (int i = 0; i < vertexNum ; i++) {
this.data[i] = data[i];
for (int j = 0; j < vertexNum; j++) {
this.edgesWeight[i][j] = edgesWeight[i][j];
}
}
// 因为是无向图所以只要遍历右上角即可,确定边的数量
for (int i = 0; i < vertexNum ; i++) {
for (int j = i + 1; j < vertexNum ; j++) {
if(edgesWeight[i][j] != INF){
edgeNum++;
}
}
}
this.edges = getEdges(edgesWeight);
// destination = new int[vertexNum];
}
class Edge{
int point1;
int point2;
int edgeWeight;
public Edge(int point1, int point2, int edgeWeight) {
this.point1 = point1;
this.point2 = point2;
this.edgeWeight = edgeWeight;
}
@Override
public String toString() {
return "Edge{" +
"point1=" + point1 +
", point2=" + point2 +
", edgeWeight=" + edgeWeight +
'}';
}
}
/**
* 还不知道边的情况如何,需要写一个方法获取
*/
public Edge[] getEdges(int[][] edgesWeight){
Edge[] edges1 = new Edge[edgeNum];
int index = 0;
for (int i = 0; i < vertexNum ; i++) {
for (int j = i + 1; j < vertexNum ; j++) {
if(edgesWeight[i][j] != INF){
edges1[index++] = new Edge(i,j,edgesWeight[i][j]);
}
}
}
return edges1;
}
/**
* 使用选择排序对边长进行从小到大排序
* !!!不能交换两个属性的值啊
*/
public void sortEdges(){
int length = this.edges.length;
for (int i = 0; i < length - 1; i++) {
Edge min = edges[i];
// int min = edges[i].edgeWeight;
int minIndex = i;
for (int j = i + 1; j < length; j++) {
if(edges[j].edgeWeight < min.edgeWeight){
min = edges[j];
minIndex = j;
}
}
if(minIndex != i){
edges[minIndex] = edges[i];
edges[i] = min;
}
}
}
/**
* 根据索引显示对应字符
*/
public char getChar(int index){
return data[index];
}
/**
* 判断加入的边的两个点是否是同一个终点,如果是则不加入此边
*/
public int getDestination(int[] destination,int point){
// int end = destination[point];
while(destination[point] != 0){
// return end;
point = destination[point];
}
return point;
}
public void kruskal(){
Edge[] bestEdges = new Edge[edgeNum];
int[] destination = new int[vertexNum];
// Edge[] bestEdges = new Edge[vertexNum - 1];
int index = 0;
sortEdges();
for (int i = 0; i < edges.length; i++) {
int end1 = getDestination(destination,edges[i].point1);
int end2 = getDestination(destination,edges[i].point2);
if(end1 != end2){
bestEdges[index++] = edges[i];
destination[end1] = end2;
// destination[edges[i].point1] = end2;
}
// if(index == vertexNum - 1){
// break;
// }
}
for (int i = 0; i < bestEdges.length; i++) {
if(bestEdges[i] != null){
System.out.printf("<%c - %c>,权值为%d\n",getChar(bestEdges[i].point1),getChar(bestEdges[i].point2),bestEdges[i].edgeWeight);
}
}
}
}
java kruskal
最新推荐文章于 2024-05-31 10:46:10 发布