题目:
基本思想:
设该图所有点集为V,V={1,2,3,4,5,6},选择连接起来的点为S,S初始化为S={1},忽略S或V-S内部各点相连情况,专注于S与V-S中的相连情况
①V-S中每个点都确认与S中的点连接的最小权值边,将其存储在closest数组,其权值存储在lowcost数组,初值都为与编号1的连接情况
如 closest[i]=j 表示与i相连的权值最小的边为 j ,lowcost[i]=5表示i相连的最小权值即(i,j)的权
无直接连接就记权值为无穷大
②找到未连接到S的各点最小权值中的最小权值,即lowcost[i]所对应的下标 i 为未连接且lowcost[i]为最小值
③将上述 i 连接到S中,连接对象为S中的 j,因为 closest[i]=j
④V-S中的每个点再判断与 i 的连接权值与已存储的最小权值,看是否需要更新最小权值连接
⑤S==V?终止 : 回到①
package algorism5;
public class Prim {
public static void prim(int n, float[][] c) {// n为编号1到n个点
float[] lowcost = new float[n + 1];// lowcost[i]为i与S中邻接点最小的权即c[i][closest[i]]
int[] closest = new int[n + 1];// closest[i]为i在S中的权最小的邻接顶点,属于S,i属于V-S,
boolean[] s = new boolean[n + 1];// 表示选择的点,true为选择
s[1] = true;// 初始值选1
for (int i = 2; i <= n; i++) {// 每个都初始化
lowcost[i] = c[1][i];// s中只有1
closest[i] = 1;// s中只有1一个点,所以其他每个最短邻接点为1
s[i] = false;// 其他初始化为未选
}
for (int i = 1; i < n; i++) {
float min = Float.MAX_VALUE;// 最大值以免影响最小值判断
int j = 1;
for (int k = 2; k <= n; k++) {// 找到已有最小邻接点中权最小的邻接点k,k属于v-s,把k赋给j
if (lowcost[k] < min && (!s[k])) {
min = lowcost[k];
j = k;
}
}
System.out.println(j + "," + closest[j]);// 将上面所得的点与其在s中的最小邻接点连接起来
s[j] = true;
for (int k = 2; k <= n; k++) {// j已经被连接,更新v-s中的点有与j连接成新的最小权边
if ((c[j][k] < lowcost[k]) && (!s[k])) {
lowcost[k] = c[j][k];
closest[k] = j;
}
}
}
}
public static void main(String args[]) {// 6个点从编号1到6,数组下标0的不用
float[][] c = new float[7][7];
for (int i = 0; i < 7; i++)// 设所有点都不连通
for (int j = 0; j < 7; j++)
c[i][j] = Float.MAX_VALUE;
c[1][4] = 5;// 对应点相连
c[1][2] = 6;
c[1][3] = 1;
c[2][3] = 5;
c[2][5] = 3;
c[3][4] = 5;
c[3][5] = 6;
c[3][6] = 4;
c[4][6] = 2;
c[5][6] = 6;
for (int i = 1; i < 7; i++) {
for (int j = 1; j <= i; j++) {
if (j == i) {
c[i][j] = 0;// 自己到自己
} else
c[i][j] = c[j][i];// 无向图对称矩阵
}
}
prim(6, c);
}
}
结果: