图结构如下
最小生成树
这里就直接打印生成路径,直接贴代码
import java.util.*;
public class KruskalPrim {
public static int[][] adjMat = null;
static {
//用二维矩阵存储图
adjMat = new int[6][6];
adjMat[0][1] = 6; adjMat[0][2] = 1; adjMat[0][3] = 5;
adjMat[1][0] = 6; adjMat[1][2] = 5; adjMat[1][4] = 3;
adjMat[2][0] = 1; adjMat[2][1] = 5; adjMat[2][3] = 5;
adjMat[2][4] = 6; adjMat[2][5] = 4;
adjMat[3][0] = 5; adjMat[3][2] = 5; adjMat[3][5] = 2;
adjMat[4][1] = 3; adjMat[4][2] = 6; adjMat[4][5] = 6;
adjMat[5][2] = 4; adjMat[5][3] = 2; adjMat[5][4] = 6;
}
public static void kruskal(){
int[] parent = new int[adjMat.length+1];
List<Edge> edgeList = new ArrayList<Edge>();
for(int i=0;i<adjMat.length;i++){
for(int j=0;j<adjMat[i].length;j++){
if(adjMat[i][j]>0)
edgeList.add(new Edge(i,j,adjMat[i][j]));
}
}
Collections.sort(edgeList);
for(Edge edge:edgeList){
//判断节点是否连通是kruskal算法的核心,主要是为了避免环的产生
int n = find(parent,edge.start);
int m = find(parent,edge.end);
if(n!=m){
parent[n] = m;
System.out.println(edge);
}
}
}
public static int find(int[] parent,int p){
while(parent[p]>0){
p = parent[p];
}
return p;
}
public static void prim(int idx){
int[] dis = new int[adjMat.length];
boolean[] check = new boolean[adjMat.length];
for(int i=0;i<dis.length;i++){
dis[i] = Integer.MAX_VALUE;
}
dis[idx] = 0;
check[idx] = true;
int count = 0;
while(count <dis.length){
System.out.print(idx+"-->");
int min = Integer.MAX_VALUE;
for(int i=0;i<adjMat.length;i++){
if(adjMat[idx][i]>0&&adjMat[idx][i]<dis[i]){
dis[i] = adjMat[idx][i];
}
}
for(int i=0;i<dis.length;i++){
if(dis[i]>0&&dis[i]<min){
idx = i;
min = dis[i];
}
}
count ++;
dis[idx] = 0;
check[idx] = true;
}
}
public static void main(String[] args) {
System.out.println("最小生成树kruskal:");
kruskal();
System.out.println("最小生成树prim:");
prim(0);
}
}
//边对象,实现Conparable结构方便排序
class Edge implements Comparable<Edge>{
int start;
int end;
int val;
public Edge(int start, int end, int val) {
this.start = start;
this.end = end;
this.val = val;
}
@Override
public int compareTo(Edge o) {
return this.val-o.val;
}
@Override
public String toString() {
return "Edge{" +
"start=" + start +
", end=" + end +
", val=" + val +
'}';
}
}
输出如下:
最小生成树kruskal:
Edge{start=0, end=2, val=1}
Edge{start=3, end=5, val=2}
Edge{start=1, end=4, val=3}
Edge{start=2, end=5, val=4}
Edge{start=1, end=2, val=5}
最小生成树prim:
0-->2-->5-->3-->1-->4-->