普利姆(Prim)算法

来源:互联网 发布:谢云流小时候捏脸数据 编辑:程序博客网 时间:2024/05/16 06:29

一.普利姆(Prim)算法思想

设:N =(V , E)是个连通网,另设U为最小生成树的顶点集,TE为最小生成树的边集。

普利姆(Prim)算法步骤:

(1)初始状态: U ={u0 },( u0 ∈V ),TE= φ,

(2)在u∈U ,v∈(V-U)所有的边(u,v)∈E中,找一条代价最小的边(u0,v0),并将边(u0,v0)并入集合TE,同时v0并入U。

(3)重复(2),直到U=V为止。

此时TE中必有n-1条边,T=(V,{TE})就是最小生成树。

注:在最小生成树的生成过程中,所选的边都是一端在U中,另一端在V-U中。选最小边的过程是一个向集合U中添加顶点的过程。

二.利用普利姆(Prim)算法构造一棵最小生成树举例

例:利用普利姆(Prim)算法对下面的连通网构造一棵最小生成树。

普利姆(Prim)算法

利用普利姆(Prim)算法构造最小生成树的步骤:

普利姆(Prim)算法 普利姆(Prim)算法

一般情况下所添加的顶点应满足下列条件:

在生成树的构造过程中,图中 n 个顶点分属两个集合:已落在生成树上的顶点集 U 和尚未落在生成树上的顶点集V-U ,则应在所有连通U中顶点u和V-U中顶点v的边中选取权值最小的边(u’,v’),并把v’添加到U中。

三.Prim(普里姆)算法描述

下面我们考虑一下如何实现这个操作过程的算法。

分析 :(1)它主要有两项操作:按条件选择一条边和将顶点加入到U集合中;(2)网中的每个顶点不是在U集合中,就是在V-U集合中。为了提高算法的时间、空间效率,我们将为这个算法设计一个辅助数组closedge,用来记录从集合U到集合V-U具有最小权值的边。对每个属于V-U集合的顶点,在辅助数组中存在一个相应的分量closedge[i-1],它包括两个域,一个域用来表示在该顶点与V-U集合中某些顶点构成的边中权最小的那条边的权值,若该顶点进入U集合,则值为0;另一个域表示这条最小权值的边对应的在V-U集合中的顶点下标。其类型定义如下所示:

#define MAX_NUM  10struct {   int adjvex;      float lowcist;}closedge[MAX_NUM];

整个算法的执行过程可以描述为:

{ 初始化closedge数组的内容;  选择某个顶点k作为生成树的根结点,并将它加入到U集合中;  重复下列操作n-1次: 选择一条满足条件的边; 输出这条边的两个端点; 修改V-U集合中的顶点信息,即与U集合中构成最小权值的边。}

假设该网以邻接矩阵的形式给出,则完整的算法为:

void Mini_SpanTree(Graph G,int k,int n){//G是网的邻接矩阵,k是生成树根结点的序号,n是网的顶点数目  for (j=0;j<n;j++)   if (j!=k) closedge[j]={k,G[k][j]};  closedge[k].lowcost=0;  for (i=1;i<n;i++)  {    k=minmun(closedge);    printf(k,closedge[k].adjvex);    closedge[k].lowcost=0;     //将顶点加入U集合中    for (j=0;j<n;j++)     if (closedge[i]&&G[k][j]<closedge[j].lowcost)       closedge[j]={k,G[k][j]};  }}
原创粉丝点击