kruskalAlgroithm克鲁斯卡尔算法(求最小生成树)

package kruskal;

import java.util.Arrays;

public class KruskalCase {

private int edgeNum; //顶点个数

private char [] vertexs; //顶点数组

private int[][] matrix;//邻接矩阵

//INF 表示不能连通

private static final int INF = Integer.MAX_VALUE;

public static void main(String[] args) {

// TODO Auto-generated method stub

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}};

KruskalCase krukalCase = new KruskalCase(vertexs,matrix);

krukalCase.print();

// EData[] edges = krukalCase.getEdges();

// System.out.println("排序前"+Arrays.toString(edges));

// krukalCase.sortEdge(edges);

// System.out.println("排序后"+Arrays.toString(edges));

krukalCase.kruskal();

}

public KruskalCase(char []vertexs,int [][]matrix) {

//初始化顶点数和边的个数

int vlen = vertexs.length;

//初始化顶点复制拷贝

this.vertexs = new char[vlen];

for(int i=0;i<vlen;i++) {

this.vertexs[i] =vertexs[i];

}

//初始化邻接矩阵

this.matrix = new int[vlen][vlen];

for(int i=0;i<vlen;i++) {

for(int j=0;j<vlen;j++) {

this.matrix[i][j] =matrix[i][j];

}

}

//统计边的条数

for(int i=0;i<vlen;i++) {

for(int j=i+1;j<vlen;j++) {

if(matrix[i][j]!=INF) {

edgeNum++;

}

}

}

}

public void kruskal() {

//表示结果数组的索引

int index =0;

//保存已有“最小生成树”中的每个顶点在最小生成树中的终点

int [] ends = new int[edgeNum];

//创建结果数组,保存最小生成树

EData[]rets = new EData[edgeNum];

//获取边

EData[]edges = getEdges();

System.out.println("边的集合"+Arrays.toString(edges));

//进行排序

sortEdge(edges);

//遍历edges数组,判断准备加入的边是否形成回路,没形成回路则加入rets,

for(int i=0;i<edgeNum;i++) {

//获取第i条边的第一个顶点(起点)

int p1 = getPosition(edges[i].start);

//获取第i条边的第二个顶点

int p2 = getPosition(edges[i].end);

//p1在最小生成树中对应的终点

int m = getEnd(ends,p1);

//p2在最小生成树中对应的终点

int n = getEnd(ends,p2);

//判断是否构成回路

if(m!=n) {

ends[m]=n; //设置m在最小生成数中的终点

rets[index++]=edges[i]; //加入到最小生成树中

}

}

System.out.println("最小生成树:");

for(int i=0;i<index;i++) {

System.out.println(rets[i]);

}

}

public void print() {

System.out.println("邻接矩阵为:\n");

for(int i=0;i<vertexs.length;i++) {

for(int j=0;j<vertexs.length;j++) {

System.out.printf("%12d\t",matrix[i][j]);

}

System.out.println();

}

}

//对edge的集合进行排序 冒泡排序

public void sortEdge(EData[] edges) {

for(int i=0;i<edges.length;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 ch 顶点的值比如 "A" "B"

* @return ch对应的顶点的下标

*/

public int getPosition(char ch) {

for(int i =0;i<vertexs.length;i++) {

if(vertexs[i]==ch) {

return i;

}

}

return -1;

}

/**

* EData的形式[["A","B",10],["B","F",7],....]

* @return

*/

public EData[] getEdges() {

int index =0;

EData [] edges = new EData[edgeNum];

for(int i=0;i<vertexs.length;i++) {

for(int j=i+1;j<vertexs.length;j++) {

if(matrix[i][j] !=INF) {

edges[index++] =new EData(vertexs[i],vertexs[j],matrix[i][j]);

}

}

}

return edges;

}

/**

* 功能:获取下标为i的顶点的终点下标,用于后面判断两个顶点的终点是否相同

* @param ends: 数组记录了各个顶点对应的终点是哪个,ends在数组遍历的过程中逐步形成,

* @param i: 对应传入数组的下标

* @return 返回的是下标为i对应的顶点的终点

*/

private int getEnd(int[] ends,int i) {//注意如果ends[i]=0则返回i

while(ends[i]!=0) {

i=ends[i];

}

return i;

}

}

//EData类对象的实例就是表示一条边

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 "<" + start + "," + end + ">" + weight;

}

}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值