算法思想:可取图中任意一个顶点V作为生成树的根,之后若要往生成树上添加顶点W,则在顶点V和W之间必定存在一条边。并且该边的权值在所有连通顶点V和W之间的边中取值最小。
一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边
代码:
//最小生成树 普里姆算法
//最小生成树 普里姆算法 采用邻接矩阵存储
void MiniSpanTree(MGraph *G)
{
int min, i, j, k;
int adjvex[MaxVex]; //保存相关顶点下标
int lowcost[MaxVex]; //保存相关顶点间边的权值
lowcost[0] = 0; //初始化第一个权值为0,即V0加入生成树
adjvex[0] = 0; //初始化第一个顶点下标为0
for (i=1; i<G->numVertexes; ++i)
{
lowcost[i] = G->arc[0][i];
adjvex[i] = 0; //将v0顶点与之有边的权值存入数组 并初始化都为v0的下标
}
for (i=1; i<G->numVertexes; ++i)
{
min = INFINITY;
j = 1;
k = 0;
while (j<G->numVertexes)
{
//如果两个顶点之间存在边并且权值小于min
if (lowcost[j]!=0 && lowcost[j]<min)
{
min = lowcost[j];
k = j;
}
++j;
}
printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边
lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已经完成任务
for (j=1; j<G->numVertexes; ++j)
{
if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j])
{
lowcost[j] = G->arc[k][j];
adjvex[j] = k;
}
}
}
}
此图表示将0作为生成树的根,然后把与相关的顶点权值存在lowcost数组中.这里1,2,3结点的权值保存在lowcost中( lowcost[i] = G->arc[0][i];)
而那些没有相邻接的顶点,权值将是无穷大,紫色表示与0相关的
int min, i, j, k;
int adjvex[MaxVex]; //保存相关顶点下标
int lowcost[MaxVex]; //保存相关顶点间边的权值
lowcost[0] = 0; //初始化第一个权值为0,即V0加入生成树
adjvex[0] = 0; //初始化第一个顶点下标为0
for (i=1; i<G->numVertexes; ++i)
{
lowcost[i] = G->arc[0][i];
adjvex[i] = 0; //将v0顶点与之有边的权值存入数组 并初始化都为v0的下标
}
那么在3个邻接点中选取权值最小的与0相邻接
for (i=1; i<G->numVertexes; ++i)
{
min = INFINITY;//开始min赋值为无穷大
j = 1;,k = 0; k表示用来保存权值最小的顶点
while (j<G->numVertexes)
{
//如果两个顶点之间存在边并且权值小于min
if (lowcost[j]!=0 && lowcost[j]<min)//如果等于0就是本身顶点,不等于权值表示是是相邻接的顶点
{
min = lowcost[j];
k = j;//保存最小的顶点值,这里k=2了
}
++j;
}
//这里打印 0,2
printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边
lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已经完成任务
![图片](https://i-blog.csdnimg.cn/blog_migrate/79de04e25e3e2b2240a1d1a93aaef639.jpeg)
这里是关键
lowcost保存的是0与各个顶点的权值,而现在lowcost[2]=0表示此顶点收入到最小二叉树
2与之相邻的结点的权值是为arc[2][i];如果2与之向邻接的顶点和lowcost也相邻,那么把邻接2个的权值,最小的赋值给lowcost,
图中表示的灰色的线表示放弃此线,相当于把最小的权值赋值给lowcost
lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已经完成任务
for (j=1; j<G->numVertexes; ++j)
{
if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j]) //这里表示的就是最小的赋值给lowcost
{
lowcost[j] = G->arc[k][j];//lowcostd获取最小的权值
adjvex[j] = k;
}
}
![图片](https://i-blog.csdnimg.cn/blog_migrate/1b64d39d6b3bcc3b02d787282d327a94.jpeg)
然后把2中与之相邻接的点找出权值最小的邻接,然后将此下标的lowcost=0;将此点纳入最小二叉树中
下面和上面一样的思想,那就不过多叙述了,根据上面,大家应该能看懂了
![图片](https://i-blog.csdnimg.cn/blog_migrate/d10b03184a3dfddf094fbd9b7ef0f98e.jpeg)
![图片](https://i-blog.csdnimg.cn/blog_migrate/ce0ed16c4bd39618d8eca81a7ffdf563.jpeg)
![图片](https://i-blog.csdnimg.cn/blog_migrate/fe0641ffa1701ca3ed0d1c3419241076.jpeg)