public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 带权路径图1
int net1[][] = { { 0, 1, 2, 3, 4, 5 },
{ 1, 0, 3, 2, 0, 0 },
{ 2, 3, 0, 0, 0, 6 },
{ 3, 2, 0, 0, 7, 0 },
{ 4, 0, 0, 7, 0, 5 },
{ 5, 0, 6, 0, 5, 0 } };
// 带权路径图2
// 带权路径图2
int net[][] = { { 0, 6, 0, 0, 7, 4 },
{ 6, 0, 3, 4, 0, 0 },
{ 0, 3, 0, 0, 0, 2 },
{ 0, 4, 0, 0, 5, 0 },
{ 7, 0, 0, 5, 0, 1 },
{ 4, 0, 2, 0, 1, 0 } };
net = prim(net1);
for (int i = 0; i < net.length; i++) {
for (int j = 0; j < net.length; j++) {
System.out.print(net[i][j]+" ");
}
System.out.println();
}
}
public static int[][] prim(int net[][]) {
int result[][] = new int[net.length][net.length];
int x = 0, y = 1;
int set[] = new int[net.length];
// 初始化结果数组
for (int i = 0; i < net.length; i++) {
for (int j = 0; j < net.length; j++) {
result[i][j] = 0;
}
}
// 将最小权值的两点放入集合
for (int i = 0; i < net.length; i++) {
for (int j = i + 1; j < net.length; j++) {
if (net[i][j] <= net[x][y] && net[i][j] != 0) {
x = i;
y = j;
}
}
}
InsertSort(set, x);
InsertSort(set, y);
// 更新结果数组的权值(无向)
result[x][y] = net[x][y];
result[y][x] = net[y][x];
// 循环 直到set集合中点的数目达到6
while(getSetNumber(set) < 6){
// System.out.println(1);
// 遍历集合中的边 获得最小权值的边 放入集合 设置result的权值
int pow = 9999;
//从第一个元素开始遍历 set[k]为一个顶点的下标+1
for (int k = 0; k < getSetNumber(set); k++) {
//遍历元素的边 i要还原下标 所以-1 因为在set数组中是用下标+1的方式储存
for (int i = set[k]-1; i < set.length; i++) {
for (int j = 0; j < set.length; j++) {
//只有不与已在集合内的元素的边(+1) 和 权值更小的边 但不为零 可以作为目标
if( !isCover(set,j+1) && net[i][j] <= pow && net[i][j] != 0){
pow = net[i][j];
// System.out.println(pow+" "+i+" "+j);
x = i;
y = j;
}
}
}
}
//跟新集合内的元素和结果的权值
InsertSort(set, x);
InsertSort(set, y);
result[x][y] = net[x][y];
result[y][x] = net[y][x];
// for (int i = 0; i < set.length; i++) {
// System.out.print(set[i]+" ");
// }
// System.out.println();
}
return result;
}
//返回数组里非0的数字的个数
public static int getSetNumber(int[] set){
for (int i = 0; i < set.length; i++) {
if(set[i] == 0)
return i;
if(i + 1 == set.length)
return set.length;
}
return 0;
}
//判断数字n 是否在set里
public static boolean isCover(int[] set, int n) {
for (int i = 0; i < set.length; i++) {
if (set[i] == n)
return true;
}
return false;
}
//动态增序插入一个数 如果这个数已经存在在数组中 就不插入
public static void InsertSort(int[] set, int num) {
num += 1;
// 数组中没有数 直接放到第一位
if (set[0] == 0)
set[0] = num;
else {
// 如果已经有相等的数 不进行插入
for (int i = 0; i < set.length; i++) {
if (num == set[i])
return;
}
for (int i = 0; i < set.length; i++) {
// 如果插入的数小于第i个数 往后偏移一位 放在第i位
if (num < set[i]) {
for (int j = set.length - 1; j > i; j--) {
set[j] = set[j - 1];
}
set[i] = num;
return;
}
}
// 如果插入的数大于所有数 放在最后
for (int i = 0; i < set.length; i++) {
if (set[i] == 0) {
set[i] = num;
return;
}
}
}
}
}
Prim算法 数组实现
最新推荐文章于 2021-08-28 15:30:56 发布