最小生成树
普里姆(prim)算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。
一个百科>>>
描述:从单一顶点开始,普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。
- 输入:一个加权连通图,其中顶点集合为V,边集合为E;
- 初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {};
- 重复下列操作,直到Vnew = V:
- 在集合E中选取权值最小的边(u, v),其中u为集合Vnew中的元素,而v则是V中没有加入Vnew的顶点(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
- 将v加入集合Vnew中,将(u, v)加入集合Enew中;
- 输出:使用集合Vnew和Enew来描述所得到的最小生成树。
时间复杂度
最小边、权的数据结构 | 时间复杂度(总计) |
---|---|
邻接矩阵、搜索 | |
二叉堆(后文伪代码中使用的数据结构)、邻接表 | |
斐波那契堆、邻接表 |
通过邻接矩阵图表示的简易实现中,找到所有最小权边共需的运行时间。使用简单的二叉堆与邻接表来表示的话,普里姆算法的运行时间则可缩减为,其中为连通图的边集大小,为点集大小。如果使用较为复杂的斐波那契堆,则可将运行时间进一步缩短为,这在连通图足够密集时(当满足条件时),可较显著地提高运行速度。
代码实现:
/* Prim算法生成最小生成树 */
void MiniSpanTree_Prim(MGraph G) {
int min, i, j, k;
/* 保存相关顶点下标 */
int adjvex[MAXVN];
/* 保存相关顶点间边的权值 */
int lowcost[MAXVN];
/* 初始化第一个权值为0,即v0加入生成树,lowcost的值为0,在这里就是此下标的顶点已经加入生成树 */
lowcost[0] = 0;
/* 初始化第一个顶点下标为0 */
adjvex[0] = 0;
/* 循环除下标为0外的全部顶点 */
for(i = 1; i < G.vertexNum; i++) {
/* 将v0顶点与之有边的权值存入数组 */
lowcost[i] = G.arc[0][i];
/* 初始化都为v0的下标 */
adjvex[i] = 0;
}
for(i = 1; i < G.vertexNum; i++) {
/* 初始化最小权值为∞,通常设置为不可能的大数字如32767、65535等 */
min = INFINITY;
j = 1;
k = 0;
/*
循环全部顶点,找到权值最小的边,同时记住邻接点的索引。
因为这些个边的就是个邻接矩阵存储,
而权值是通过循环加到数组中的lowcost数组中,
lowcost数组中的每一个非0和非∞的元素的下标索引即邻接点的索引。
*/
while(j < G.vertexNum) {
/* 如果权值不为0且权值小于min */
if(lowcost[j] != 0 && lowcost[j] < min) {
/* 则让当前权值成为最小值 */
min = lowcost[j];
/* 将当前最小值的下标存入k */
k = j;
}
j++;
}
/* 打印当前顶点边中权值最小的边 */
printf("edge:(%d, %d), wegiht:%d\n", adjvex[k], k, lowcost[k]);
/* 将当前顶点的权值设置为0,表示此顶点已经完成任务,
lowcost数组元素置为0的位置不再加入元素,
意味着该结点的权值最小的一条边已经确定
*/
lowcost[k] = 0;
/* 循环所有顶点,
通过lowcost中最小元素的下标,
去将对应的邻接点的所有边权值加入到lowcost数组,
同时将下标索引加到
*/
for(j = 1; j < G.vertexNum; j++) {
/* 如果下标为k顶点各边权值小于此前这些顶点未被加入生成树权值*/
if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j]) {
/* 将较小的权值存入lowcost相应位置 */
lowcost[j] = G.arc[k][j];
/* 将下标为k的顶点存入adjvex */
adjvex[j] = k;
}
}
}
}
运行结果:
然后说下算法的思想:
从连通网N={V,E}中的某一顶点U0出发,选择与它关联的具有最小权值的边(U0,v),将其顶点加入到生成树的顶点集合U中。以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u,v),把它的顶点加入到集合U中。如此继续下去,直到网中的所有顶点都加入到生成树顶点集合U中为止。
还是不太明白的小伙伴,希望本篇文章能对你有帮助>>>戳我