最小生成树:Prim算法

最小生成树: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 VU为不包含集合 U U U中元素的顶点集

集合 V − U V-U VU中顶点与集合 U U U顶点满足在图中已构成边,从这些权值对应的边中选出权值最小的边 (此边是由前面两个集合中各取一个顶点组成的),将满足此条件的集合 V − U V-U VU中的顶点加入到集合 U U U

k是最新closedge数组中最小lowcost值对应顶点的下标

最小边 ( u 0 , v 0 ) (u_0,v_0) (u0,v0)是满足以上条件的两个顶点构成的边【 u 0 ∈ U u_0 \in U u0U v 0 ∈ V − U v_0 \in V-U v0VU

构造最小生成树过程辅助数组中各分量的值

邻接矩阵存储表示

#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 n1个顶点进行分析
如下写出对第二个顶点的分析


上图过程对下图表中内容

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Uncertainty!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值