图的生成树:是该连通图的一个极小连通子图,含有图的全部顶点,但只有构成一棵树的(n-1)条边
一幅加权图的最小生成树(MST):在生成树的基础上,要求树的(n-1)条边的权值之和是最小的
public class PrimDemo {
public static void main(String[] args) {
char[] datas = new char[] {'A','B','C','D','E','F','G'};
int vertexs = datas.length;
// 邻接矩阵 (∵ 是加权边 ∴ 表示两个顶点不连通得用个大数而非0)
int[][] weightEdges = new int[][] {
{10000,5,7,10000,10000,10000,2},
{5,10000,10000,9,10000,10000,3},
{7,10000,10000,10000,8,10000,10000},
{10000,9,10000,10000,10000,4,10000},
{10000,10000,8,10000,10000,5,4},
{10000,10000,10000,4,5,10000,6},
{2,3,10000,10000,4,6,10000}
};
MST mst = new MST();
mst.createGraph(vertexs, datas, weightEdges);
mst.showGraph();
mst.prim(4);
}
}
class MST {
private Graph graph;
public void createGraph(int vertexs, char[] datas, int[][] weightEdges) {
graph = new Graph(vertexs);
int i, j;
for(i = 0; i < vertexs; i++) {
graph.datas[i] = datas[i];
for(j = 0; j < vertexs; j++)
graph.weightEdges[i][j] = weightEdges[i][j];
}
}
/**
* 普利姆算法
* @param v 从图的 v顶点 开始生成MST E.G. 'A' → 0, 'B' → 1 ...
*/
public void prim(int v) {
// 标记 顶点是否已被访问
int[] visited = new int[graph.vertexs];
// 把当前结点标记为 1
visited[v] = 1;
// 记录选定的2个顶点的索引
int h1 = -1;
int h2 = -1;
int minWeight = 10000;
// n个顶点, 找出 n-1 条边
for(int k = 1; k < graph.vertexs; k++) {
// 双重for: 确定 [新一次生成的子图(图越来越大)] 中, 哪两个顶点的权值最小
// ~ 顶点i 表示被访问的结点(也同是子图中的顶点)
for(int i = 0; i < graph.vertexs; i++) {
// ~ 顶点j 表示还没有被访问的结点
for(int j = 0; j < graph.vertexs; j++) {
// 子图越来越大, 需要if的次数也越来越多
if(visited[i] == 1 && visited[j] == 0
&& graph.weightEdges[i][j] < minWeight) {
minWeight = graph.weightEdges[i][j];
h1 = i;
h2 = j;
}
}
}
System.out.printf("<%c, %c>\tweight = %d\n"
, graph.datas[h1], graph.datas[h2], minWeight);
visited[h2] = 1;
minWeight = 10000;
}
}
public void showGraph() {
graph.showGraph();
}
}
class Graph {
int vertexs; // 图中顶点个数
char[] datas; // 顶点的值
int[][] weightEdges; // 加权边
public Graph(int vertexs) {
this.vertexs = vertexs;
datas = new char[vertexs];
weightEdges = new int[vertexs][vertexs];
}
public void showGraph() {
for(int[] link : weightEdges)
System.out.println(Arrays.toString(link));
}
}
原文:https://www.cnblogs.com/liujiaqi1101/p/12489890.html