您的位置:首页 > 理论基础 > 数据结构算法

数据结构 之 Prim算法的应用 之 MST(最小生成树)

2018-03-26 11:10 393 查看
算法:Prim 应用:对一个带权无向图生成 (权值)最小生成树 (程序来自《天勤 数据结构 高分笔记》) 今日一签,赠给奋斗的自己和你们:
人生不能像做菜,把所有的材料都准备好了才下锅。——李安《饮食男女》 讲述算法前,先做如下的说明:1. 带权无向图的存储把一个共有N个结点的带权无向图的信息(边以及边的权值)存放在一个大小为N乘N的二维方阵中。带权无向图的N个结点的编号是0至N-1。方阵元素[i][j]表示节点编号是i和j的2个节点之间的边的权值,行标 = 列标 的 方阵元素 规定 其值是0,表示结点自身到自身的权值是0;宏定义一个常量INF,把它的值设为大于图中所有边权值的一个数,这个自定,若图中结点i与结点j之间没有边,规定二维方阵中的元素[i][j]的值是INF,表示两个结点之间的权值是无穷大。图由结点和边构成,所以,结构体定义如下:#define MAXSIZE 100#define INF     500 typedef struct{    int no;         // 存放结点的编号    char info;     // 存放结点的信息}VertexType;         // 结点 typedef struct{    int n,e;                     // n: 存放图的结点总数,e: 存放图的边的总数    int edges[MAXSIZE][MAXSIZE]; // 存放带权无向图的边和边的权值信息    VertexType vex[MAXSIZE];     // 存放带权无向图的结点信息}MGraph; // 图 2. 树树只有一个根,根下是各个子树,并且很重要的一点是这些子树互不相交,所以树中是没有环的,所以,在做这个算法的时候,不能到最后生成的是一个带环的图,避免出现环,需要一个判断语句,这个判断语句什么时候应该出现,它的内容是什么,读程序的时候请格外注意。 3. C++ 的 引用& 函数void Prim(MGraph g, int v0, int &sum)参数中的sum是C++中的引用类型,表示它的值在传进函数以后,其值需要跟着函数的功能实现而被改变。

C++代码: 
#include <iostream>

using namespace std;

#define MAXSIZE 100
#define INF     500

typedef struct
{
int no;
char info;//
}VertexType;

typedef struct
{
int n,e;
int edges[MAXSIZE][MAXSIZE];
VertexType vex[MAXSIZE];
}MGraph;

void Prim(MGraph g, int v0, int sum)
{
int lowcost[g.n] = {0};
int vset[g.n] = {0};
int v;
int i,j,k;
int min;

v = v0;
vset[v] = 1;
for(int i=0;i<g.n;++i)
lowcost[i] = g.edges[v][i];
sum = 0;

for(int i=0;j<g.n-1;i++){
min = INF;
for(int j=0;j<g.n;++j)
if(vset[j]==0 && lowcost[j] < min)
{
min = lowcost[j];
k=j;
}

v = k;
vset[v] = 1;
sum += min;

for(int j=0;j<g.n;++j)
if(vset[j]==0 && g.edges[v][j]<lowcost[j])
lowcost[j] = g.edges[v][j];
}
}

int main()
{

}

程序的说明:1. 把一个很大的结构体MGraph作为函数的参数,浪费空间,这个在实际中需要改进。作为考试代码,完全可以先这样写。 2. 外层的for循环,只需要执行g.n-1次(即 图的结点总数-1)即可,因为参数v0表示MST的第一个起始结点,又根据算法可以满足执行g.n-1次找到剩下的n-1个结点就完成MST的确定 3. 数组vset大小是图的结点个数,初始化时元素都为0,随着算法的进行,如果某个结点i归入了MST,那么vset[i]置为1,否则为0,而程序中反复出现的判断语句vset[j]==0可以保证找到的树是一个不带环的图,这一点非常重要!!待整个prim函数执行完,vset中的元素就会全部是1。 4. 数组lowcost大小是图的结点个数,这个变量记录的是当前MST 到 剩余其他结点 的 最小路径值,一开始MST只是结点V0,内层的第一个for循环用于使用当前的lowcost找到一个新的应该并入MST的结点v,内层的第二个for循环用于通过刚找到的这个新的并入MST的结点v更新lowcost 5.外层循环执行g.n-1(简写为n-1)次,<
b218
/p>内层的2个for循环执行g.n(简写为n)次,基本操作共执行(n-1)*(2n)次,所以时间复杂度取大的量级为:n的平方,也可以看出,Prim算法生成MST时间复杂度只与结点的个数有关,与边没有关系,所以Prim算法适合 稠密图(结点多,边少) 6.变量min表示 当前的MST树(中的各个节点)距离 剩下的 结点的 最小路径值 的 最小值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: