最小生成树——普里姆算法

当我们要求解n个连接城市之间的路线问题,就需要我们进行一个计算。

而在连通网上面,我们称这类问题为最小代价生成树(最小生成树)问题。今天我们主要讨论的是用普里姆算法实现最小生成树。

如图所示,a图是一个有权值的连通图。要对其进行最小生成树求解,假设初始点为V1,寻找与1有关系而且权值最小的顶点

                                                                  (图源严蔚敏版数据结构)           V2进行访问,再从点V2寻找下一个有关系而且权值最小的顶点,若访问的点将构成闭合回路,将进行回溯,回溯到上一个点,再进行访问。直至走完所以顶点。

代码实现:

/**求顶点位置**/
int Locatvex(ArrayGraph G,char u)
{
    int i,a;
    for(i=0;i<MAXN;i++)
    {
        if(u==G.vex[i])///循环求得u顶点的位置
        {
            a=i;
            return a;///返回a
        }
    }
    a=-1;
    return a;
}
/**返回最小代价边**/
int minimum(struct node *closedage)
{
    int MIN=INF;///MIN用于表示最短距离
    int k=-1;
    int i;
    for(i=0;i<MAXN;i++)
    {
        if(closedage[i].lowcost<MIN&&closedage[i].lowcost!=0)///如果两顶点有关系,且权值小于MIN
        {
            MIN=closedage[i].lowcost;///更新MIN,直至找到最近的顶点
            k=i;
        }
    }
    return k;
}
/**最小生成树**/
void primG(ArrayGraph G,char u)///u表示规定的起始点
{
    int i,j;
    int k;
    k=Locatvex(G,u);///求取顶点位置
    for(i=0;i<MAXN;++i)
    {
        if(i!=k)
        {
            closedage[i].data=u;
            closedage[i].lowcost=G.arcs[k][i];
        }
    }
    closedage[u].lowcost=0;///初始化

    for(i=0;i<MAXN;i++)///循环寻找下一个顶点
    {
        k=minimum(closedage);///k为两顶点最小权值
        printf("%c\t",G.vex[k]);///输出
        closedage[k].lowcost=0;
        for(j=0;j<MAXN;j++)
        {
            if(G.arcs[k][j]<closedage[j].lowcost)
            {
                closedage[j].data=G.vex[k];
                closedage[j].lowcost=G.arcs[k][j];
            }
        }
    }
}

运行结果:

时间复杂度:O(n²)

假设图中共有n个顶点,则进行第一个循环的频度为n,第二个循环的频度为n-1。而重新求取最小代价边的频度为n。因此时间复杂度为O(n²)

猜你喜欢

转载自blog.csdn.net/jin_jue_qi/article/details/82729798
今日推荐