给定一个带权的无向连通图,能够连通该图的全部顶点且不产生回路的子图即为该图的生成树;
一个连通图的生成树是一个极小连通子图,它含有图中全部N个顶点且只有足以构成一棵树的N-1条边;
首先看这样一个场景:
思路:需要保证修路的条数尽可能少且每条路的长度尽可能短,即
import java.util.Arrays;
public class PrimAlgorithm {
public static void main(String[] args) {
char[] data = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
int verNum = data.length;
int[][] weight = new int[][] { // 1024表示无边
{ 1024, 5, 7, 1024, 1024, 1024, 2 },
{ 5, 1024, 1024, 9, 1024, 1024, 3 },
{ 7, 1024, 1024, 1024, 8, 1024, 1024 },
{ 1024, 9, 1024, 1024, 1024, 4, 1024 },
{ 1024, 1024, 8, 1024, 1024, 5, 4 },
{ 1024, 1024, 1024, 4, 5, 1024, 6 },
{ 2, 3, 1024, 1024, 4, 6, 1024 } };
// 创建MGraph对象
MGraph graph = new MGraph(verNum);
// 创建MinTree对象
MinTree minTree = new MinTree();
minTree.creatGraph(graph, verNum, data, weight);
minTree.showGraph(graph);
// 测试prim算法
System.out.println("-----从" + data[0] + "开始的最小生成树-----");
minTree.prim(graph, 0);
}
}
//创建最小生成树->村庄的图
class MinTree {
// 创建图的邻接矩阵
/**
* @param graph 图对象
* @param verNum 图的节点个数
* @param data 图的各个节点的值
* @param weight 图的邻接矩阵
*/
public void creatGraph(MGraph graph, int verNum, char[] data, int[][] weight) {
for (int i = 0; i < verNum; i++) {// 顶点
graph.data[i] = data[i];
for (int j = 0; j < verNum; j++) {// 边
graph.weight[i][j] = weight[i][j];
}
}
}
// 显式图的邻接矩阵
public void showGraph(MGraph graph) {
for (int i = 0; i < graph.verNum; i++) {
System.out.print(" " + graph.data[i]);
}
System.out.println();
int j = 0;
for (int[] link : graph.weight) {
System.out.println(graph.data[j++] + " " + Arrays.toString(link));
}
}
// prim算法
/**
* @param graph 图对象
* @param v 表示最小生成树的起始点
*/
public void prim(MGraph graph, int v) {
// visted用于标记节点是否被访问过 默认初始值都为0表示所有节点都没有被访问过
int[] visited = new int[graph.verNum];
// 将起始点v标记为已经访问
visited[v] = 1;
// 用 indexBegin 和 indexEnd 记录两个顶点的下标
int indexBegin = -1;
int indexEnd = -1;
int minWeight = 1024;
for (int k = 0; k < graph.verNum-1; k++) {// 普利姆算法结束后,一共有graph.verNum-1条边,故k∈[0,graph.verNum-2]
// 下面双重循环的作用寻找已经访问过的节点和为访问过的节点之间权值最小的未访问节点
for (int i = 0; i < graph.verNum; i++) {// i节点表示访问过的节点
for (int j = 0; j < graph.verNum; j++) {// j节点表示未被访问过的节点
if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {
minWeight = graph.weight[i][j];
indexBegin = i;
indexEnd = j;
}
}
} // 此时已经找到
System.out.println("边<" + graph.data[indexBegin] + "," + graph.data[indexEnd] + "> 权值:" + minWeight);
//将信息存入minTreeEdage
// 将新找到的节点标记为已访问
visited[indexEnd] = 1;
minWeight = 1024;// 重置minWeight用于找下一个待加入子图的节点
}
}
}
class MGraph {
int verNum; // 表示图的节点个数
char[] data;// 存放节点数据
int[][] weight; // 邻接矩阵
public MGraph(int verNum) {
this.verNum = verNum;
this.data = new char[verNum];
weight = new int[verNum][verNum];
}
}
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有