Prim算法生成最小生成树

来源:互联网 发布:英语语言变迁 知乎 编辑:程序博客网 时间:2024/04/26 01:59
void MiniSpanTree_Prim(MGraph G)//prim算法生成最小生成树{int min,i,j,k;int adjvex[MAXVEX];//保存相关顶点下标int lowcost[MAXVEX];//保存相关顶点间边的权值lowcost[0] = 0;//初始化第一个权值为0,即v0加入生成树。lowcost的值为0,在这里就是此下标的顶点已经加入生成树adjvex[0] = 0;//初始化第一个顶点下标为0for(i = 1;i < G.numVertexes;i++)//循环下标为0外的全部顶点{lowcost[i] = G.arc[0][i];//将v0顶点与之有边的权值存入数组adjvex[i] = 0;//初始化都为v0的下标}for(i = 1;i < G.numVertexes;i++){min = INFINITY;//初始化最小权值为无穷,通常设置为不可能的大数字如32767、65535等j = 1;k = 0;while(j < G.numVertexes)//循环全部顶点{if(lowcost[j] != 0 && lowcost[j] < min){//如果权值不为0且权值小于minmin = lowcost[j];k = j;}j++;}printf("(%d,%d)",adjvex[k],k);//打印当前顶点边中权值最小边lowcost[k] = 0;//将当前顶点的权值设置为0,表示此顶点已经完成任务for(j = 1;j < G.numVertexes;j++)//跟8~12行初始化类似{if(lowcost[j] != 0&&G.arc[k][j] < lowcost[j]){//若下标为k顶点各边权值小于此前这些顶点未被加入生成树权值lowcost[j] = G.arc[k][j];//将较小权值存入lowcostadjvex[j] = k;}}}}

1、程序开始运行,我们由第4~5行,创建两个一位数组lowcost和adjvex,长度都为顶点个数为9。

2、第6~7行我们分别给这两个数组的第一个下标位赋值为0,arjvex[0] = 0其实意思就是我们现在从顶点v0开始(事实上,最小生成树从哪个顶点开始计算都无所谓,我们假定从v0开始),lowcost[0] = 0就表示v0已经被纳入到最小生成树中,之后凡是lowcost数组中的值被设置为0就是表示此下标的顶点被纳入最小生成树。

3、第8~12行表示我们读取图7-6-3的右图邻接矩阵的第一行数据。将数值赋值给lowcost数组,所以此时lowcost数组值为{0,10,65535,65535,65535,11,65535,65535,65535},而arjvex则全部为0。此时我们已经完成整个初始化工作,准备开始生成。



4、第13~36行,整个循环过程就是构造最小生成树的过程。

5、第15~16行,将min设置为了一个极大值65535,它的目的是为了找到一定范围内的最小权值。j是用来做顶点下标循环的变量,k是用来存储最小权值的顶点下标。

6、第17~25行,循环中不断修改min为当前lowcost数组中的最小值,并用k保留此最小值的顶点下标。经过循环后,min = 10,k = 1,。注意第19行if判断的lowcost[j] != 0表示已经是生成树的顶点不参与最小权值的查找。

7、第26行,因k = 1,adjvex[1] = 0,所以打印结果为(0,1),表示v0至v1边为最小生成树的第一条边。如图7-6-4所示。



8、第27行,此时我们将lowcost[k] = 0就是说顶点v1纳入到最小生成树中。此时lowcost数组值为{0,0,65535,65535,65535,11,65535,65535,65535}。

\\写到这里的时候我突然想到这本质不就相当于把v0与v1并入一个集合里面,v0、v1之间的权值改为0,将v0与v1看做一个整体就行了,下面再重新探测这个整体与其余所有点之间的权值,看是否要更新,每次循环都是要看这个整体与整体之外的所有点之间的权值是否要更新

9、第28~35行,j循环由1至8,因k = 1,查找邻接矩阵的第v1行的各个权值,与lowcost的对应值比较,若更小则修改lowcost值,并将k值存入adjvex数组中。因第v1行有18、16、12均比65535小,所以最终lowcost数组的值为:{0,0,18,65535,65535,11,16,65535,12}.adjvex数组的值为:{0,0,1,0,0,0,1,0,1}。这里第30行if判断的lowcost[j] != 0也说明v0和v1已经是生成树的顶点不参与最小权值的比对了。

10、再次循环,由第15行到第26行,此时min = 11,k = 5,adjvex[5] = 0。因此打印结构为(0,5)。表示v0至v5边为最小生成树的第二条边,如图7-6-5所示。



11、接下来执行到第36行,lowcost数组的值为:{0,0,18,65535,26,0,16,65535,12}。adjvex数组的值为:{0,0,1,0,5,0,1,0,1}。

12、之后,按照此方式继续模拟,通过不断的转换,构造的过程如图7-6-6中图1~图6所示。




下面是Prim算法的实现定义:

假设N = (P,{E})是连通网,TE是N上最小生成树中边的集合。算法从U = {u0}(u0∈V),TE = {}开始。重复执行下述操作:在所有u ∈ U,v∈V--U的边(u,v)∈E中找一条代价最小的边(u0,v0)并入集合TE,同时V0并入U,直至U = V为止。此时TE中必有n - 1条边,则T = (V,{TE})为N的最小生成树。

此算法的时间复杂度为O(n^2)。


——————引自《大话数据结构》

0 0
原创粉丝点击