Prim算法(java)
作者:互联网
一、Prim算法介绍
Prim(普利姆)算法是一种构造最小生成树的算法。Prim算法的时间复杂度为 O ( ∣ V ∣ 2 ) O(|V|^2) O(∣V∣2),不依赖于 E E E,因此它适用于求解边稠密的图的最小生成树。
二、Prim算法原理
(1)初始时从图中任取一顶点加入最小生成树MinTree顶点集合中。
(2)选择一个与当前MinTree中顶点集合距离最近的顶点,并将该顶点和相应的边加入MinTree中,每次操作后MinTree中的顶点数和边数都增1。
(3)重复(2)步骤,直到所有顶点都加入到MinTree中,得到最小生成树。此时MinTree中有
n
−
1
n-1
n−1条边。
三、Prim算法图解
构造图(a)的最小生成树过程如下:
(1)从顶点
V
1
V_{1}
V1开始,离
V
1
V_{1}
V1最近的三个顶点为
V
2
、
V
3
、
V
4
V_{2}、V_{3}、V_{4}
V2、V3、V4,选取权值最小的顶点
V
3
V_{3}
V3,加入顶点集合中,并将边<
V
1
,
V
3
V_{1},V_{3}
V1,V3>加入最小生成树中。(如图b所示)
(2)此时顶点集合为(
V
1
,
V
3
V_{1},V_{3}
V1,V3),离顶点集合中最近的顶点为
V
2
、
V
4
、
V
5
、
V
6
V_{2}、V_{4}、V_{5}、V_{6}
V2、V4、V5、V6,选取权值最小的顶点
V
6
V_{6}
V6,加入顶点集合中,并将边<
V
3
,
V
6
V_{3},V_{6}
V3,V6>加入最小生成树中。(如图c所示)
(3)此时顶点集合为(
V
1
,
V
3
,
V
6
V_{1},V_{3},V_{6}
V1,V3,V6),离顶点集合中最近的顶点为
V
2
、
V
4
、
V
5
V_{2}、V_{4}、V_{5}
V2、V4、V5,选取权值最小的顶点
V
4
V_{4}
V4,加入顶点集合中,并将边<
V
6
,
V
4
V_{6},V_{4}
V6,V4>加入最小生成树中。(如图d所示)
(3)此时顶点集合为(
V
1
,
V
3
,
V
6
、
V
4
V_{1},V_{3},V_{6}、V_{4}
V1,V3,V6、V4),离顶点集合中最近的顶点为
V
2
、
V
5
V_{2}、V_{5}
V2、V5,选取权值最小的顶点
V
2
V_{2}
V2,加入顶点集合中,并将边<
V
3
,
V
2
V_{3},V_{2}
V3,V2>加入最小生成树中。(如图e所示)
(4)此时顶点集合为(
V
1
,
V
3
,
V
6
、
V
4
、
V
2
V_{1},V_{3},V_{6}、V_{4}、V_{2}
V1,V3,V6、V4、V2),离顶点集合中最近的顶点为
V
5
V_{5}
V5,选取权值最小的顶点
V
5
V_{5}
V5,加入顶点集合中,并将边<
V
2
,
V
5
V_{2},V_{5}
V2,V5>加入最小生成树中。(如图f所示)
(5)此时顶点集合为(
V
1
,
V
3
,
V
6
、
V
4
,
V
2
、
V
5
V_{1},V_{3},V_{6}、V_{4},V_{2}、V_{5}
V1,V3,V6、V4,V2、V5),所有顶点已加入到集合中。最小生成树的边为<
V
1
,
V
3
V_{1},V_{3}
V1,V3>、<
V
3
,
V
6
V_{3},V_{6}
V3,V6>、<
V
6
,
V
4
V_{6},V_{4}
V6,V4>、<
V
3
,
V
2
V_{3},V_{2}
V3,V2>、<
V
2
,
V
5
V_{2},V_{5}
V2,V5>。
四、Prim算法代码实现
package com.haiyang.algorithm.prim;
/**
* @author haiYang
* @create 2022-02-01 16:57
*/
public class PrimAlgorithm {
public static void main(String[] args) {
char[] data = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int vertexs = data.length;
//maxValue表示两个顶点之前没有边
int maxValue = Integer.MAX_VALUE;
//邻接矩阵的关系使用二维数组表示,maxValue表示两个点不联通
int[][] weight = new int[][]{
{maxValue, 5, 7, maxValue, maxValue, maxValue, 2},
{5, maxValue, maxValue, 9, maxValue, maxValue, 3},
{7, maxValue, maxValue, maxValue, 8, maxValue, maxValue},
{maxValue, 9, maxValue, maxValue, maxValue, 4, maxValue},
{maxValue, maxValue, 8, maxValue, maxValue, 5, 4},
{maxValue, maxValue, maxValue, 4, 5, maxValue, 6},
{2, 3, maxValue, maxValue, 4, 6, maxValue}};
Graph graph = new Graph(vertexs, data, weight);
prim(graph, 0);
}
/**
* @param graph 图
* @param v 开始顶点
*/
public static void prim(Graph graph, int v) {
//标记已访问顶点
int[] visited = new int[graph.vertexs];
//将开始顶点标记已访问
visited[v] = 1;
//h1、h2标记最小的权值weight位置
int h1 = -1;
int h2 = -1;
//记录最小权值
int minWeight = Integer.MAX_VALUE;
//除开始顶点,将其他graph.verrtexs-1个顶点进行选取
for (int k = 1; k < graph.vertexs; k++) {
//遍历图的所有情况,找到此轮的最小权值连接的顶点
for (int i = 0; i < graph.vertexs; i++) {
for (int j = 0; j < graph.vertexs; j++) {
//选取的顶点要求:i是已经选取的的顶点,j是为选取的顶点,找到满足情况的最小权值,记录位置
if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {
minWeight = graph.weight[i][j];
h1 = i;
h2 = j;
}
}
}
//将此轮选取的最小权值连接的顶点信息输出
System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值=" + minWeight);
//将此轮选取的顶点标记为已访问
visited[h2] = 1;
//重新初始化minWeight值
minWeight = Integer.MAX_VALUE;
}
}
}
/**
* 图类
*/
class Graph {
int vertexs; //表示顶点个数
char[] data;//存放顶点数据
int[][] weight; //使用邻接矩阵存放边
public Graph(int vertexs, char[] data, int[][] weight) {
this.vertexs = vertexs;
this.data = data;
this.weight = weight;
}
}
标签:Prim,int,graph,权值,maxValue,最小,算法,顶点,java 来源: https://blog.csdn.net/weixin_43698993/article/details/122770231