一、普里姆算法(Prim)
1、条件:图为邻接矩阵结构(Adjacency List)
2、原理:假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,TV 是 WN 上最小生成树中顶点的集合,TE 是最小生成树中边的集合。显然,在算法执行结束时,TV=V,而 TE 是 E 的一个子集。在算法开始执行时,TE 为空集,TV 中只有一个顶点,因此,按普里姆算法构造最小生成树的过程为:在所有“其一个顶点已经落在生成树上,而另一个顶点尚未落在生成树上”的边中取一条权值为最小的边,逐条加在生成树上,直至生成树中含有 n-1条边为止
3、code
void MiniSpanTree_Prim(MGraph G)
{
int min,i,j,k;
int adjvex[MAXVEX]; /*保存相关顶点下标*/
int lowcost[MAXVEX]; /*保存相关顶点的权值,存放的是最小生成树到剩下顶点的最小权值*/
int lowcost[0]=0; /*初始化第一个权值为0,即v0加入生成树,假设v0下标为0*/
for(i=1;i<G.numVertexes;i++)
{
lowcost[i]=G.arc[0][i]; /*arc为邻接矩阵的弧数组*/
/*将第一个顶点v0与之有边的权值存入数组*/
adjvex[i]=0; /*初始化都为v0的下标*/
}
for(i=1;i<G.numVertexes;i++)
{
min=INFINITY; /*初始化最小权限值为∞,便于比较*/
j=1;i=0;
while(j<G.numVertexes)
{
if(lowcost[j]!=0&&lowcost[j]<min) /*lowcost[j]==0表示已将该顶点归入生成树了,不必比较了*/
{
min=lowcost[j]; /*当前权值为最小值*/
k=j; /*记录该值*/
}
j++;
}
printf("(%d,%d)",adjvex[k],k); /*即adjvex[k]顶点与k顶点之间有同路*/
lowcost[k]=0; /*将当前顶点的权值设为0,表示将该顶点归入生成树*/
for(j=1;j<G.numVertexes;j++)
{
/*下面的循环的意思是在所有“其一个顶点已经落在生成树上,而另一个顶点尚未落在生成树上”的边中取一条权值为最小的边*/
if(lowcost[j]!=0 && G.arc[k][j]<lowcost[j])
{
/*若下标为k顶点各个权值小于此前这些顶点未被加入生成树权值*/
lowcost[j]=G.arc[k][j]; /*将较小的权值存入lowcost*/
adjvex[j]=k; /*将小标为k的顶点存入adjvex*/
}
}
}
}
一、克鲁斯卡尔算法(Kruskal)
1、条件:边集数组结构(Edge)
2、原理:设有一个有n个顶点的连通网N={V,E},最初先构造一个只有n个顶点,没有边的非连通图T={V, E},图中每个顶点自成一个连通分量。当在E中选到一条具有最小权值的边时,若该边的两个顶点落在不同的连通分量上,则将此边加入到T中;否则将此边舍去,重新选择一条权值最小的边。如此重复下去,直到所有顶点在同一个连通分量上为止。
3、code
/*对编辑数组Edge结构的定义*/
typedef struct
{
int begin; /*起始顶点下标*/
int end; /*终止顶点下标*/
int weight; /*权值*/
}Edge;
/*Kruskal算法生成最小生成树*/
void MiniSpanTree_Kruskal(MGraph G)
{
int i,n,m;
Edge edges[MAXEDGE]; /*定义边集数组*/
int parent[MAXVEX]; /*定义一数组用来判断边与边是否行程环路*/
/*此处省略将邻接矩阵G转化为边集数组edges并按权由小到大排序的代码*/
for(i=0;i<G.numVertexes;i++)
{
parent[i]=0; /*初始化数组值为0*/
}
for(i=0;i<G.numVertexes;i++)
{
n=Find(parent,edges[i].begin);
m=Find(parent,edges[i].end);
if(n!=m) /*说明此边没有与现有的生成树行程环路*/
{
parent[n]=m; /*将此边的结尾顶点放入小标为起点的parent中*/
/*表示n与m在同一个集合中*/
printf("(%d,%d) %d",edges[i].begin,edges[i].end,edges[i].weight);
}
}
}
int Find(int *parent,int f) /*查找连线顶点的尾部下标*/
{
while(parent[f]>0)
f=parent[f];
return f;
}
转载于:https://blog.51cto.com/xiaoahei/1221294