最小生成树

本文详细介绍了普里姆算法构造最小生成树的过程,包括MST性质、算法思想、具体实现以及时间复杂度分析。通过实例展示算法如何在连通网中寻找权重最小的边集合形成最小生成树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普里姆(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
}
/**
6
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 6 4
3 5 6
4 6 2
5 6 6
0 0 0
*/

4. 测试输出



5. 时间复杂度

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值