Prim算法

97 阅读2分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。

Prim算法

相关概念

生成树:连通图的生成树是包含全部顶点的一个极小连通子图
生成树的代价:在无向连通网中,生成树上各边的权值之和
最小生成树:在无向连通网中,代价最小的生成树

Prim算法——基本思想

关键:是如何找到连接 U 和 V-U 的最短边

算法:Prim
输入:无向连通网G=(V,E)
输出:最小生成树T=(U,TE)
 1. 初始化:U = {v}; TE={ }; 
 2. 重复下述操作直到U = V: 
           2.1 在E中寻找最短边(i,j),且满足i∈U,j∈V-U;
           2.2 U = U + {j};
           2.3 TE = TE + {(i,j)};

运行实例

image.png

初始化:
U={v0} 
V-U={v1 , v2 , v3 , v4 , v5 }
cost={(v0 , v1)34,(v0 , v2)46,(v0, v3)∞,(v0 , v4)∞,(v0, v5 )19} 

image.png

第一次迭代:
U={v0 , v5 } 
V-U={v1 , v2 , v3 , v4}
cost={(v0 , v1)34, (v5 , v2)25, (v5, v3)25, (v5 , v4)26}

image.png

第二次迭代:
U={v0 , v5 , v2 } 
V-U={v1 , v3 , v4 }
cost ={(v0 , v1)34, (v2, v3)17, (v5 , v4)26} 

image.png

第三次迭代:
U={v0 , v5, v2 , v3 } 
V-U={v1 ,  v4}
cost={(v0 , v1)34, (v5 , v4)26} 

image.png

第四次迭代:
U={v0 , v5, v2 , v3 , v4 } 
V-U={v1 }
cost ={(v4 , v1)12} 

image.png

image.png

Prim算法——存储结构

图采用什么存储结构呢?

需要不断读取任意两个顶点之间边的权值---->图采用邻接矩阵存储

如何存储候选最短边集(连接U和V-U的候选最短边)?

数组adjvex[n]:表示候选最短边的邻接点
数组lowcost[n]:表示候选最短边的权值

代码实现

void Prim(MGraph *G, int v){   
    int i, j, k, adjvex[MaxSize], lowcost[MaxSize];
    for (i = 0; i < G->vertexNum; i++){
        lowcost[i] = G->edge[v][i]; adjvex[i] = v;
    }
    lowcost[v] = 0;   
    for (k = 1; k < G->vertexNum; i++){
        j = MinEdge(lowcost, G->vertexNum)
        printf("(%d, %d)%d ", j, adjvex[j], lowcost[j]);    
        lowcost[j] = 0;    
        for (i = 0; i < G->vertexNum; i++)
            if G->edge[i][j] < lowcost[i] {
                lowcost[i] = G->edge[i][j]; adjvex[i] = j;
            }
     }
}