普里姆算法介绍
普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图
普利姆的算法如下:
设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合
若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1
若集合U中顶点ui与集合V-U中的顶点vj之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点vj加入集合U中,将边(ui,vj)加入集合D中,标记visited[vj]=1
重复上述步骤,直到U与V相等,即所有顶点都被标记为访问过,此时D中有n-1条边
提示: 单独看步骤很难理解,我们通过实例和代码来讲解,比较好理解
4.4代码思路
举例来说明,就用下面这张图,起始顶点起始无所谓,因为顶点有 7 个,边数最少为 6 条边,最后得到的 6
条边中,其路径长度都是所有边中路径长度最短的
第一步:选取顶点 A ,并标记顶点 A 已被访问,求取最短路径
A – > B :路径长度为 5
A – > C :路径长度为 7
A – > G :路径长度为 2
选取最短路径 ,其长度为 2
标记顶点 G 已被访问过
第二步:同样也是求取最短路径
A – > B :路径长度为 5
A – > C :路径长度为 7A – > G :G 已经被访问过,不考虑
G – > B :路径长度为 3
G – > E :路径长度为 4
G – > F :路径长度为 6
选取最短路径
标记顶点 B 已被访问过
第三步:同样也是求取最短路径
A – > B :B 已经被访问过,不考虑
A – > C :路径长度为 7
A – > G :G 已经被访问过,不考虑
G – > B :B 已经被访问过,不考虑
G – > E :路径长度为 4
G – > F :路径长度为 6
class MGraph {
int verxs; // 表示图的节点个数
char[] data;// 存放结点数据
int[][] weight; // 存放边,就是我们的邻接矩阵
public MGraph(int verxs) {
this.verxs = verxs;
data = new char[verxs];
weight = new int[verxs][verxs];
}
//创建图的邻接矩阵
/**
*
* @param graph 图对象
* @param verxs 图对应的顶点个数
* @param data 图的各个顶点的值
* @param weight 图的邻接矩阵
*/
public void createGraph(MGraph graph, int verxs, char data[], int[][] weight) {
int i, j;
for (i = 0; i < verxs; i++) {// 顶点
graph.data[i] = data[i];
for (j = 0; j < verxs; j++) {
graph.weight[i][j] = weight[i][j];
}
}
}
// 显示图的邻接矩阵
public void showGraph(MGraph graph) {
for (int[] link : graph.weight) {
System.out.println(Arrays.toString(link));
}
}
}