# Kruskal和Prim最小生成树java实现

Kruskal最小生成树

//思路参考http://blog.csdn.net/luomingjun12315/article/details/47700237
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;

public class KruskalMST {
private static int MAX = 100;
private ArrayList<Edge> edge = new ArrayList<Edge>();//整个图的边
private ArrayList<Edge> target = new ArrayList<Edge>();//目标边，最小生成树
private int[] parent = new int[MAX];//标志所在的集合
private static double INFINITY = 99999999.99;//定义无穷大
private double mincost = 0.0;//最小成本
private int n;//结点个数

public static void main(String args[]){
KruskalMST sp = new KruskalMST();
sp.init();
sp.kruskal();
sp.print();
}
//初始化
public void init(){
Scanner scan = new Scanner(System.in);
int p,q;
double w;

System.out.println("spanning tree begin!Input the node number:");
n = scan.nextInt();
System.out.println("Input the graph(-1,-1,-1 to exit)");

while(true){
p = scan.nextInt();
q = scan.nextInt();
w = scan.nextDouble();
if(p < 0 || q < 0 || w < 0){
break;
}
Edge e = new Edge();
e.start = p;
e.end = q;
e.cost = w;
}

mincost = 0.0;

for (int i = 1; i <= n; ++i){
parent[i] = i;
}
scan.close();
}
//集合合并
public void union(int j, int k){
for(int i = 1; i <= n; ++i){
if(parent[i] == j){
parent[i] = k;
}
}
}
//Kruskal算法主体
public void kruskal(){
//找剩下的n-2条边
int i = 0;
while(i < n-1 && edge.size() > 0){
//每次取一最小边，并删除
double min = INFINITY;
Edge tmp = null;
for(int j = 0; j < edge.size(); ++j){
Edge tt = edge.get(j);
if(tt.cost < min){
min = tt.cost;
tmp = tt;
}
}
int jj = parent[tmp.start];
int kk = parent[tmp.end];
//去掉环，判断当前这条边的两个端点是否属于同一棵树
if(jj != kk){
++i;
mincost += tmp.cost;
union(jj,kk);
}
edge.remove(tmp);
}
if(i != n-1){
System.out.println("no spanning tree");
}
}
//打印结果
public void print(){
double sum = 0;
for(int i = 0; i < target.size(); ++i){
Edge e = target.get(i);
System.out.println("the " + (i+1) + "th edge:" + e.start + "---" + e.end + "   cost:" + e.cost);
sum += e.cost;
}
System.out.println("the MST cost:"+sum);
}
}

class Edge
{
public int start;//始边
public int end;//终边
public double cost;//权重
}

Prim最小生成树

//思路参考http://blog.csdn.net/yeruby/article/details/38615045
import java.util.Scanner;

public class PrimMST {
private static int MAX = 100;
private static int[][] graph = new int[MAX][MAX];
private int[] lowcost = new int[MAX];// 标志所在的集合
private int[] mst = new int[MAX];//
private static int INFINITY = 99999999;// 定义无穷大
private int mincost = 0;// 最小成本
private static int mstcost = 0;// 最小成本
private static int n;// 结点个数
private int middle;// 中间结点
private int sum = 0;

public static void main(String args[]) {
PrimMST sp = new PrimMST();
sp.init();
mstcost = sp.prim(graph, n);
System.out.println("最小生成树权值和为：" + mstcost);
}

// 初始化
public void init() {
Scanner scan = new Scanner(System.in);
int p, q, w;
System.out.println("spanning tree begin!Input the node number:");
n = scan.nextInt();
System.out.println("Input the graph(-1,-1,-1 to exit)");
while (true) {
p = scan.nextInt();
q = scan.nextInt();
w = scan.nextInt();
if (p < 0 || q < 0 || w < 0) {
break;
}
graph[p][q] = w;
graph[q][p] = w;
}
scan.close();
}

// prim算法主体
public int prim(int graph[][], int n) {
for (int i = 2; i <= n; i++) {
lowcost[i] = graph[1][i];
mst[i] = 1;
}
mst[1] = 0;
for (int i = 2; i <= n; i++) {
mincost = INFINITY;
middle = 0;
for (int j = 0; j <= n; j++) {
if (lowcost[j] < mincost && lowcost[j] != 0) {
mincost = lowcost[j];
middle = j;
}
}
System.out.println(mst[middle] + "--" + middle + "==" + mincost);
sum += mincost;
lowcost[middle] = 0;
for (int j = 0; j <= n; j++) {
if (graph[middle][j] < lowcost[j]) {
lowcost[j] = graph[middle][j];
mst[j] = middle;
}
}
}
return sum;
}
}