最小生成树

来源:互联网 发布:行业分析知乎 编辑:程序博客网 时间:2024/04/29 15:10

普里姆(Prime)算法和克鲁斯卡尔(Kruskal)算法是两个利用最小生成树(MST)性质构造最小生成树的经典算法。下面是普里姆算法构造最小生成树。

图的存储结果采用邻接矩阵。

1. MST性质

假设N = (V, {E})是一个连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则比存在一条包含边(u, v)的最小生成树。


2. Prime算法思想

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


3.算法如下:

int minclosedge(Closedge *closedge, int n) {  //求得当前U中代价最小的边,有结构closedge标识    int i = 0, k;    while (closedge[i].lowcost == 0) i++;     //找到第一个没有加入U的顶点下标    k = i;    for (i++;i < n;i++) {        if (closedge[i].lowcost != 0 && closedge[k].lowcost > closedge[i].lowcost)            k = i;    }    return k;}void prime(MGraph *G, int u) {    //从顶点编号u开始,即初始U={u}  /*    struct {        int adjvex;               //adjvex表示顶点下标        int lowcost;              //closedge[i-1]时,lowcost为下标为i的顶点与下标为adjvex的代价    }closedge[G->vexnum];    */    Closedge closedge[G->vexnum];    int i, j, k;    k = u - 1;                    //u-1为顶点u的存储下标    closedge[k].lowcost = 0;    closedge[k].adjvex = 0;    for (i = 0;i < G->vexnum;i++) //初始化求得u与其他每个顶点间的代价        if (i != k) {            closedge[i].lowcost = G->arcs[i][k];            closedge[i].adjvex = k;        }    for (i = 1;i< G->vexnum;i++) {            //the remaining (G->vexnum - 1) vertices        k = minclosedge(closedge, G->vexnum); //求出下一个节点:第k顶点        closedge[k].lowcost = 0;              //第k顶点并入U集合        printf("(V%d-V%d) ",closedge[k].adjvex + 1, k + 1);        for (j = 0;j < G->vexnum;j++)            if (closedge[j].lowcost > G->arcs[j][k]) { //新顶点并入U集合,重新选择最小边                closedge[j].lowcost = G->arcs[j][k];                closedge[j].adjvex = k;            } //if    } //for i}/**61 2 61 3 11 4 52 3 52 5 33 4 53 6 43 5 64 6 25 6 60 0 0*/

4. 测试输出



5. 时间复杂度

设n为网中的顶点数,算法的时间复杂度为O(n^2)。

普里姆算法适合求解边稠密的连通网的最小生成树。


原创粉丝点击