public class test4_6_1 {
static float[] lowcast;
static int[] closest;
static boolean[] s;
public static void prim(int n,float[][] c){
lowcast = new float[n]; //到顶点[i]最小的权值
closest = new int[n]; //到顶点[i]最小权值的点
s = new boolean[n]; //顶点[i]是否被加入
//1.初始化
s[0] = true; //率先把第一个点加入
for(int i=1;i<n;i++){
lowcast[i] = c[0][i]; //初始化,设到第[i]个点最小的权值是现有第一个点到此点的权值
closest[i] = 0; //初始化,设第一个加进去的点是到第[i]个点最小权值的点
s[i] = false;
}
for(int i=1;i<n;i++){ //添加n-1个点
//2.找最小-j
float min = Float.MAX_VALUE; //找最小的权值
int j=1; //找最小的点的序号,初始值为1的原因是初始化循环已经设置为1
for(int k=1;k<n;k++){
if((min>lowcast[k])&&(!s[k])){ //若有还没加进去的点,且此点对应边最小权值小于min
min = lowcast[k];
j = k;
}
}
s[j] = true; //将找找最小的点加进来
//3.调整
for(int k=1;k<n;k++){
if((c[j][k]<lowcast[k])&&(!s[k])){ //若新加进去的点到其他没加进去的点的权值小于没加进去点本身
lowcast[k] = c[j][k];
closest[k] = j;
}
}
}
}
public static void main(String[] args) {
int n = 4; //点的个数
float[][] c = {{ 0, 4, 9, 21}, //边权
{ 4, 0, 8, 17},
{ 9, 8, 0, 16},
{21,17,16, 0}};
prim(n,c);
int sum=0;
for(int i=1;i<n;i++){
sum += lowcast[i];
System.out.print("<"+closest[i]+","+i+">"+" ");
System.out.println(lowcast[i]);
}
System.out.println("最小生成树权和最小为:"+sum);
}
}
运行结果如下:
<0,1> 4.0
<1,2> 8.0
<2,3> 16.0
最小生成树权和最小为:28
时间复杂度:O(n^2),适用于边多的情况。