最小生成树:Prim算法
构造连通图的最小代价生成树
(连通所有顶点且带权边之和最小)
Prim算法是以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树
下面最小生成树拍摄自教材《大话数据结构》
无向图
顶点数组
邻接矩阵
使用Prim创造最小生成树过程
假设从顶点
V
0
V_0
V0 出发(图中任何一顶点均可),顶点
V
1
,
V
5
V_1,V_5
V1,V5到顶点
V
0
V_0
V0两个权值分别为10,11中,所以对于顶点
V
0
V_0
V0来说,顶点
V
1
V_1
V1到顶点
V
0
V_0
V0的权值最小,该权值为10,将其对应的边
(
V
0
,
V
1
)
(V_0,V_1)
(V0,V1)纳入最小生成树
顶点
V
1
V_1
V1的各边权值 18,12,16以及11进行比较,其中权值最小为 11,将边
(
V
0
,
V
5
)
(V_0,V_5)
(V0,V5)纳入最小生成树
接着从顶点
V
5
V_5
V5的各边权值17,26以及18,12,16进行比较,其中权值最小为 12,将边
(
V
1
,
V
8
)
(V_1,V_8)
(V1,V8)纳入最小生成树
接着从顶点
V
8
V_8
V8的各边权值8,21以及18,16,17,26进行比较,其中权值最小为 8,将边
(
V
2
,
V
8
)
(V_2,V_8)
(V2,V8)纳入最小生成树
接着从顶点
V
2
V_2
V2的各边权值22以及21,16,17,26进行比较,其中权值最小为 16,将边
(
V
1
,
V
6
)
(V_1,V_6)
(V1,V6)纳入最小生成树
接着从顶点
V
6
V_6
V6的各边权值24,19以及22,21,26进行比较,其中权值最小为 19,将边
(
V
6
,
V
7
)
(V_6,V_7)
(V6,V7)纳入最小生成树
接着从顶点
V
7
V_7
V7的各边权值16,7以及22,21,24,26进行比较,其中权值最小为 7,将边
(
V
7
,
V
4
)
(V_7,V_4)
(V7,V4)纳入最小生成树
接着从顶点
V
4
V_4
V4的各边权值20以及22,21,24,16进行比较,其中权值最小为16,将边
(
V
7
,
V
3
)
(V_7,V_3)
(V7,V3)纳入最小生成树
至此图中全部顶点全部连通,最小生成树构造完成
集合
U
U
U为顶点集
V
V
V的子集
集合
V
−
U
V-U
V−U为不包含集合
U
U
U中元素的顶点集
集合 V − U V-U V−U中顶点与集合 U U U顶点满足在图中已构成边,从这些权值对应的边中选出权值最小的边 (此边是由前面两个集合中各取一个顶点组成的),将满足此条件的集合 V − U V-U V−U中的顶点加入到集合 U U U中
k是最新closedge数组中最小lowcost值对应顶点的下标
最小边 ( u 0 , v 0 ) (u_0,v_0) (u0,v0)是满足以上条件的两个顶点构成的边【 u 0 ∈ U u_0 \in U u0∈U, v 0 ∈ V − U v_0 \in V-U v0∈V−U】
构造最小生成树过程辅助数组中各分量的值
邻接矩阵存储表示
#define MaxInt 32767 //表示极大值,即无穷大
#define MVNum 100 //最大顶点数
typedef char VerTexType; //顶点的数据类型为字符型
typedef int ArcType; //边的权值类型为整型
typedef struct{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //边表(邻接矩阵)
int vexnum,arcnum; //图的当前顶点数和边数
}AMGraph;
辅助数组closedge定义
typedef struct{
VerTexType adjvex; //最小边在集合U中的顶点
ArcType lowcost; //最小边对应的权值
}closedge[MVNum];
Prim算法
无向网G以邻接矩阵形式存储,从顶点u出发构造G的最小生成树T,输出T的各条边
void MiniSpanTree_Prim(AMGraph G, VerTexType u){ //u为顶点信息
k=LocateVex(G,u); //k为顶点u的下标
for(int j=0; j<G.vexnum; ++j) //对于集合V-U的每一个顶点Vj,初始化closedge[j]
if(j!=k)
closedge[j]={u,G.arcs[k][j]}; //closedge[]={adjvex,lowcost}
closedge[k].lowcost=0; //初始化,U={u}
for(int i=1; i<G.vexnum; ++i){ //选择其余n-1个顶点
k=Min(closedge); //求出T的下一个结点:第k个顶点,closedge[k]中存有最小边
u0=closedge[k].adjvex; //u0为最小边的一个顶点,u0 ∈ U
v0=G.vexs[k]; //v0为最小边的另一个顶点,v0 ∈ V-U
cout << u0 << v0; //输出当前的最小边(u0,v0)
closedge[k].lowcost=0; //第k个顶点并入集合U
for(int j=0; j<G.vexnum; ++j)
if(G.arcs[k][j]<closedge[j].lowcost) //新顶点并入集合U后重新选择最小边
closedge[j]={G.vexs[k],G.arcs[k][j]}; //closedge[]={adjvex,lowcost}
}
}
顶点数组vexs
邻接矩阵arcs
上图过程对下图表中内容
进入for循环开始对其余
n
−
1
n-1
n−1个顶点进行分析
如下写出对第二个顶点的分析
上图过程对下图表中内容