Minimum spanning tree algorithm-Prim algorithm

Prim algorithm

Suppose G = (V, E) is a connected network with n vertices, T = (U, TE) is the minimum spanning tree of G, where U is the vertex set of T, TE is the edge set of T, U and TE Is initially empty. Algorithm process:

  1. First take any vertex from V (assuming v 1 ) and incorporate it into U, then U = {v 1 }
  2. Then, as long as U is the true subset of V (ie U⊂V), find the shortest (that is, the smallest weight) edge from all the edges where one endpoint is already in T and the other endpoint is still outside T, assuming that (v i , v j ), where v i ∈U, v j ∈VU, and merge the edges (v i , v j ) and vertices v j into the edge set TE and vertex set U of T, and so on, Each time a vertex and an edge are merged into the spanning tree, until n-1 times, all n vertices are merged into the vertex set of the spanning tree T, then U = V, and TE contains n-1 edges , T is the minimum spanning tree finally obtained.

The steps of the prim algorithm:

1. Divide the vertex set into two parts-U (selected part), V (unselected part)

2. Find the edge with the smallest weight from the two parts each time

3. Connect the vertices into U

4. Repeat 1 until all vertices are drawn into U.

In order to facilitate the implementation of the algorithm, an auxiliary array minedge [vtxptr] is attached to record the edge with the smallest cost from U to VU (ie, the edge with the smallest weight). For each vertex v ∈ VU, there is a minedge [v] component in the auxiliary array. Each component includes two fields: the ver field stores the vertex attached to the edge in the U, and the lowcost field stores the weights on the edge.

The specific algorithm is as follows:

#include <stdio.h>
// 最大顶点数
#define MaxVertexNum 50

typedef char VertexType;
typedef int Adjmatrix;
// 邻接矩阵
typedef struct {
        VertexType vex[MaxVertexNum];// 顶点数组,类型假定为char
        Adjmatrix arcs[MaxVertexNum][MaxVertexNum];// 邻接矩阵,类型假定为int
}MGraph;

typedef int VRType;
typedef struct{
        VertexType ver;
        VRType lowcost;
}MinEdge[MaxVertexNum];
MinEdge minedge;// 从顶点集U到V-U的代价最小的边的辅助数组

// 返回顶点u在MGraph的vex数组中的下标,以此作为顶点u在辅助数组中的下标
// 若G中存在顶点u,则返回该顶点在图中的位置;否则返回-1
int vtxNum(MGraph G,int u,int n){
        // u是顶点,n是图G的顶点总数
        int k;
        for(k = 0;k < MaxVertexNum;k++){
               if(G.vex[k] == u){
                       return k;
               }
        }
        return -1;
}
int min(MGraph G,MinEdge MINI,int n){
        int i=0,j,k,min;
        while(!MINI[i].lowcost){
                i++;
        }
        min = MINI[i].lowcost;// 第一个不为0的值
        k=i;
        for(j = i+1;j < n;j++){
                if(MINI[j].lowcost > 0 && MINI[j].lowcost<min){
                        min = MINI[j].lowcost;
                        k=j;
                }
        }
        return k;// 返回最小值在辅助数组中的序号
}
void prim(MGraph G,VertexType u,int n){
        // G是采用邻接矩阵存储结构表示的图,u是顶点,n是顶点个数,以u作为出发点
        int k,v,j;
        k=vtxNum(G,u,n);// 取顶点u在辅助数组中的下标
        for(v = 0;v<n;v++){// 辅助数组初始化,v是每个顶点,此处是初始顶点u与顶点v的关系
                if(v!=k){
                        minedge[v].ver = u;//顶点域全部赋值为u点
                        minedge[v].lowcost = G.arcs[k][v];//距离域全部赋值为u到其他点的距离
                }
        }
        // 初始化,U={u}
        minedge[k].lowcost = 0;
        for(j = 0;j < n;j++){
                k=min(G,minedge,n);//k为辅助数组中值最小的点对应的序号
                printf("edge:%d-%d",minedge[k].ver,G.vex[k]);// 输出生成树的边
                minedge[k].lowcost = 0;// 第k顶点并入U集合
                for(v=0;v<n;v++){
                        if(G.arcs[k][v] < minedge[v].lowcost){
                                // 新顶点并入U集合后,重新选择最小边
                                minedge[v].ver=G.vex[k];
                                minedge[v].lowcost=G.arcs[k][v];
                        }
                }
        }
}

Recommend to watch a video: https://b23.tv/BV19J411n76b

Published 381 original articles · praised 85 · 80,000 views +

Guess you like

Origin blog.csdn.net/weixin_40763897/article/details/105487546