普里姆算法思路

 算法思想:可取图中任意一个顶点V作为生成树的根,之后若要往生成树上添加顶点W,则在顶点V和W之间必定存在一条边。并且该边的权值在所有连通顶点V和W之间的边中取值最小。

一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边

 C语言代码如下:

//最小生成树 普里姆算法    采用邻接矩阵存储
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; inumVertexes; ++i)
	{
		lowcost[i] = G->arc[0][i];
		adjvex[i] = 0;				//将v0顶点与之有边的权值存入数组  并初始化都为v0的下标
	}

	for (i=1; inumVertexes; ++i)
	{
		min = INFINITY;

		j = 1;
		k = 0;

		while (jnumVertexes)
		{
			//如果两个顶点之间存在边并且权值小于min
			if (lowcost[j]!=0 && lowcost[j]numVertexes; ++j)
		{
			if (lowcost[j]!=0 && G->arc[k][j]arc[k][j];
				adjvex[j] = k;
			}
		}
	}
}


 首先是变量的定义,min在每次循环中都存放着lowcost数组中最小的权值。

adjvex与lowcost数组中的下标分别对应了该图中的顶点,如下标为1对应了第2个顶点(顶点的序号从0开始)。

例如adjvex[3] = 5  lowcost[3] = 8即表示序号为5的顶点(即第6个顶点)到序号为3(两个数组的下标都为3 即第4个顶点)的顶点的边的权值为8

接着初始化lowcost[0]与adjvex[0]为0,即表示第0号结点加入生成树,lowcost[i] = 0表示第i个结点加入到生成树中

然后 一个循环将adjvex数组的值全都置为0并且将v0到其他顶点的权值都存入lowcost数组中。

一个包含所有顶点的大循环,所有的工作都在该循环体内完成

①假设现在是第一次循环 即第一个顶点加入生成树,第23行~33行,求得所有与该结点相邻的顶点的边上的最小的权值,并将该权值存放min中,而与其相邻的那个顶点的序号存入k中。即找到一个顶点k并且v0到k的权值是所有v0的邻接点中最小的。

/输出当前顶点边中权值最小的边  即输出adjvex[k], k 因为是第一次循环 所有adjvex[k] = 0, k即刚才所得到的那个权值最小的相邻的顶点的序号。即表示adjvex[k]号顶点到k号顶点

③lowcost[k] = 0; 表示 第k号顶点已经加入到生成树种

④第36行~43行  if (lowcost[j]!=0 && G->arc[k][j]arc[k][j];  即k顶点到j顶点的权值为 G->arc[k][j];  

以后每次加入一个新的顶点都要看其与其邻接点的边上的权值是否要小于lowcost数组中对应顶点的权值。如果小于就修改

然后找到Lowcost数组中最小的权值 并将其与顶点输出

你可能感兴趣的:(数据结构)