美文网首页
图-最小生成树-Prim

图-最小生成树-Prim

作者: 如春天 | 来源:发表于2020-08-11 09:16 被阅读0次

    普利姆算法(Prim)

    1).输入:一个加权连通图,其中顶点集合为V,边集合为E;

    2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;

    3).重复下列操作,直到Vnew = V:

    a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

    b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

    4).输出:使用集合Vnew和Enew来描述所得到的最小生成树

    示例:

    EXP.png

    说明:

    • adjvex数组存放的是对应顶点的前驱,即当选定v2为权最小加入最小生成树时,adjvex[2]=0.在代码的一开始adjvex全部置为0,因为v0的算法起始点。
    • lowcost置为0时表示的时已经将对应顶点加入最小生成树,比如lowcost[0]=0,即表示生成树集合U=为{V0},当然了,当U=V(顶点集)时,算法结束。
    • 这里很多循环是从1开始的,因为v0已经被加入了U集(lowcost[0]=0),从0开始浪费一次循环,当然如果从0开始也不会报错。注意第一个for循环是在初始化v0到其他各顶点的权值,从i=1开始时因为从v0到v0的边没有意义,当然了如果你把对角线设置为0的话,其实从0开始也没区别。
    • 在第一次for循环里,初始化所有顶点对应adjvex都为0,因为从0开始找最小权值,找到了的话他的前驱一定也只能是v0。
    #include "邻接矩阵.h"
    #define INFINITY 65535
    void Prim(MGraph G){
        int min, i, j, k; /*k为最小值对应的下标*/
        int adjvex[MAXVEX]; /*保存的是每次循环开始的那个起始点下标*/
        int lowcost[MAXVEX];/*表示相关顶点之间的权值*/
        lowcost[0] = 0; /*表示下标为0的顶点即V0已经加入最小生成树*/
        adjvex[0] = 0; /*从顶点V0开始*/
        for(i = 1; i < G.numVertexes; i++){
            lowcost[i] = G.arc[0][i];/*将与V0顶点有边的顶点全部存入数组*/
            adjvex[i] = 0; /*全部初始化为V0的下标0*/
    
        }
        /*至此完成初始化工作 开始循环构造最小生成树*/
        for(i = 1; 1 < G.numVertexes; i++){
            min = INFINITY; /*初始化最小值为∞*/
            j = 1; k = 0;
            /*从1开始的原因已经在上面说明部分指出了,因为从0开始没有意义,V0已经在U集里了*/
            /*这个while循环每次从更新过的lowcost数组中找出了为0(即已经加入最小生成树)的最小值,找到之后对应的数组索引就是下一个要加入U集的顶点,把它赋给k*/
            while(j < G.numVertexes){
                if(lowcost[j]!=0 && lowcost[j] < min){
                    /*如果权值不为0(尚未被纳入最小生成树)且权值小于min*/
                    min = lowcost[j];
                    k = j;
                }
                j++;
            }
            printf("(%d %d)", adjvex[k], k);/*打印当前顶点边中权值最小的边*/
            lowcost[k] = 0; /*k顶点已经被纳入最小生成树*/
            /*更新 新起始点到各顶点之间的权值 起始点已经从0变掉了,所以应该比较从0到各顶点的权值与从新起始点到各顶点的权值,取小者*/
            for(j = 1; j < G.numVertexes; j++){
                if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
                    lowcost[j] = G.arc[k][j];
                    adjvex[j] = k; /*同样的,更新对应的起始点下标,如果值更新比如v2->v4对应权值由v0->v4的xxx更新为更小的为yyy,则adjvex[4]=2;如果值没有更新的话,比如v0->v3权值还是更小的那一个,那他的adjvex也不更新,还是adjvex[3]=0,表示他的起始顶点为v0*/
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:图-最小生成树-Prim

          本文链接:https://www.haomeiwen.com/subject/kgwjdktx.html