ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

普利姆算法

2022-01-01 19:31:43  阅读:134  来源: 互联网

标签:普利 辅助 int 权值 算法 数组 顶点 close


普利姆算法

一:介绍:

(一):原理介绍

Prim算法构造最小生成树过程如下图所示:

​ 1、首先从图中任选一个顶点加入树T中,此时最小生成树T中就只含有一个顶点

​ 2、然后选择与当前最小生成树T中顶点集合距离最近的顶点,并将该顶点和相应的边加入最小生成树T中,每次操作树T中的顶点数量和边都加一。

​ 3、执行1,2两步,当图中的所有顶点都并入到T中,T就是最小生成树了。此时T中必有n-1条边
在这里插入图片描述

(二):算法思路介绍

​ 1、先初始化辅助数组,即从起始点到其他顶点的权值保存到数组中,并标志起始点

​ 2、循环执行以下操作(循环次数为图中顶点的数量减一,因为起始点不算)

​ (1)、定位数组中权值最小的权值,从而找到对应的下一个要加入的顶点。

​ (2)、在辅助数组中将新加入的顶点的权值置为0(自己到自己的距离为0)

​ (3)、跟新辅助数组,在新加入定点之后,集合T中的顶点到其他顶点的最小距离会变化,所以跟新新加入的顶点到其他顶点的距离,如果比原来的小,则跟新,否则不跟新。

二:代码

(一):结构

#ifndef DATASTRUCTURE_MST_H
#define DATASTRUCTURE_MST_H

#include <stdio.h>
#include "../Graph/Graph.h"
//#include "../Graph/Graph.c"

//生成树的类型定义
typedef struct {			
    VertexType adjvex;      //较早加入当前集合T的顶点(权值最小边的起始点)
    VRType lowcost;         //以该顶点为起始点的边的权值
}Edge;                      //辅助数组

typedef Edge closeEdge[MAX_VERTEX_NUM];     //创建一个辅助数组,表示已经加入到T中集合的顶点到其他顶点的最近距离

//在辅助数组中找到权值最小的边的数组下标
int Minimum(MGraph G,closeEdge close);

//普里母算法
void MinSpanTree_Prim(MGraph G,VertexType v);

#endif //DATASTRUCTURE_MST_H

(二):算法

#include "MST.h"

/**
 * 普利姆算法
 * @param G     无向网
 * @param v     开始顶点(随意)	初始为顶点1
 */
void MinSpanTree_Prim(MGraph G,VertexType v){
    int k = LocateVex(G,v);
    closeEdge close;		//辅助数组
    //初始化辅助数组,将与该起始点有关的所有边的信息:边的起始点和权值,初始化到辅助数组中
    //如初始顶点为1,那么有顶点1相连的有顶点2,3,4,则顶点1到2,3,4为其边上的权值,而与顶点5,6不相邻,所以为INFINITY
    //其中辅助数组的大小为图中顶点的数量,因此对应起始点与图中顶点的权值,即close[i].adjvex表示的是起始顶点,i对应的是顶点在
    //G中顶点数组的下标,所以可以通过i来找到顶点值
    for (int i = 0; i < G.vexnum; ++i) {
        if (i!=k){			
            close[i].adjvex = k;
            close[i].lowcost = G.arcs[k][i].adj;
        }
    }

    //因为起始点已经在最小生成树中了,所以需要将其辅助数组置0,或者因为从该点开始的,所以距离为0
    close[k].lowcost = 0;

    //选择下一个点,并更新辅助数组中的信息
    for (int i = 1; i < G.vexnum; ++i) {        //为什么从1开始,因为目前已经有一个在最小生成树中了
        k = Minimum(G,close);                   //找到权值最小的边所在数组的下标
        printf("v%d \t v%d\t",G.vexs[close[k].adjvex],G.vexs[k]);           //输出选择的路径
        close[k].lowcost = 0;                   //入树之后需要将权值设置为0

        //因为加入了一个顶点,那么辅助数组中的权值可能就会发生改变,所以,需要从新加入的顶点开始,比较其到其他邻接顶点的权值
        //如果小的就需要更新
        for (int j = 0; j < G.vexnum; ++j) {
            if (G.arcs[k][j].adj<close[j].lowcost){
                close[j].lowcost = G.arcs[k][j].adj;
                close[j].adjvex = k;

            }
        }
        printf("\n");
    }
}


//在辅助数组中找到权值最小的边的数组下标
int Minimum(MGraph G,closeEdge close){
    int min = INFINITY;			//为无向网,所以INFINTIY表示最大距离
    int index;
    for (int i = 0; i < G.vexnum; ++i) {
        if (close[i].lowcost>0&&close[i].lowcost<min){  //当权值为0的时候,说明顶点已经归到了最下生成树中了
            min = close[i].lowcost;
            index = i;
        }
    }
    return index;
}

/**
 * 确定顶点v在图中的位置
 * @param G
 * @param v		为顶点值
 * @return		如果在图的顶点数组中找到,则返回在数组中的下标,否则返回-1;
 */
int LocateVex(MGraph G,VertexType v){		
    for (int i = 0; i < G.vexnum; ++i) {
        if (v == G.vexs[i]){
            return i;
        }
    }
    return -1;
}

标签:普利,辅助,int,权值,算法,数组,顶点,close
来源: https://blog.csdn.net/weixin_43288447/article/details/122270029

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有