明确:也是最小生成树问题
典型例题:
求解思路:
1.排序
2.保证不形成回路(终点不重合)
代码:
package cn;
import java.util.Arrays;
import java.util.Random;
public class Kruskal {
static final int INF = 99;
int edgeNum; //边的个数
char[] vertexs; //顶点数组
int[][] matrix; //邻接矩阵
public Kruskal(char[] vertexs, int[][] matrix) {
this.vertexs = vertexs;
this.matrix = matrix;
//统计边的条数
for (int i = 0; i < vertexs.length; i++) {
for (int j = i + 1; j < vertexs.length; j++) {
if (this.matrix[i][j] != Kruskal.INF) {
edgeNum++;
}
}
}
}
//打印
public void show (){
for (int i = 0; i < vertexs.length; i++) {
for (int j = i+1; j < vertexs.length; j++) {
System.out.printf("%5d\n", matrix[i][j]);
}
}
}
public static void main(String[] args) {
char[] vertexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int martix[][] = {
{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}
};
Kruskal kruskal=new Kruskal(vertexs,martix);
kruskal.kruskalDemo();
}
//获取边
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;
}
//对边进行排序(冒泡)
public void sort (Edata[]edata){
for (int i = 0; i < edata.length - 1; i++) {
for (int j = 0; j < edata.length - i - 1; j++) {
if (edata[j].weight > edata[j + 1].weight) {
Edata t = edata[j];
edata[j] = edata[j + 1];
edata[j + 1] = t;
}
}
}
}
//获取顶点
public int getPosition ( char ch){
for (int i = 0; i < vertexs.length; i++) {
if (vertexs[i] == ch) {
return i;
}
}
return -1;
}
//获取终点,不能形成回路
//ends[]:记录各个顶点对应的终点是哪一个,数组是在遍历的过程中,逐步形成
public int getEnd ( int[] ends, int i){
while (ends[i] != 0) {
i = ends[i];
}
return i;
}
//Krudkal算法
public void kruskalDemo(){
int index=0; //表示结果数组的索引
int [] ends=new int[edgeNum];
Edata[]rets=new Edata[edgeNum];
//获取所有边
Edata[] edges=getEdges();
System.out.println(Arrays.toString(edges)+"边数总和:"+edges.length);
//按从小的到大进行排序
sort(edges);
//遍历数组,判断 是否形成回路,不是,则将边加入
for(int i=0;i<edgeNum;i++){
//获取边的起点和终点的位置
int p1=getPosition(edges[i].start);
int p2=getPosition(edges[i].end);
//判断是否形成回路
int i1 = getEnd(ends, p1);
int i2 = getEnd(ends, p2);
if(i1!=i2){ //说明没有形成回路
ends[i1]=i2;
rets[index++]=edges[i];
}
}
System.out.println("最小生成树为:");
for(int i=0;i<index;i++){
System.out.println(rets[i]);
}
}
}
package cn;
import com.sun.corba.se.impl.orbutil.graph.Graph;
public 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=" + weight +
'}';
}
}