【数据结构】拾遗(二):连通图邻接矩阵图的prim算法

连通图的prim算法主要是求连通图的最小生成树。主要的思想是从图上某一点开始,找与之最近的(权重最小的)顶点,保存边和顶点。然后找与这两个点最近的(权重最小的)的顶点。循环往之,并每次保存边和边的顶点,就得到了最小生成树。

具体到算法的实现,根据参考资料,主要是两个数组,一个数组是保存当前未各顶点与已存顶点的最小距离lowcost,另一个一个数组是保存与之最小距离的顶点下标mst,比较并找寻最小的,然后将找到的顶点的lowcost清零(相当于剔除这个点),并根据新的顶点更新lowcost和mst。

这里我用前几天遍历的那个图随机赋值几个权重:


具体的求生成树的演算过程在电脑上写出来太烦了,我比较懒,就整理了我自己的演算草稿,贴图在下:


下面是实现的源代码,我就在前几天写的那个c++中的类添加了两个函数,然后将初始化的权重改了一下,在外部define了一个MAX_Weight。设置值为1000,当然还可以更大。

//prim求最短生成树,前提要是连通图
queue<int> Map::prim()
{
	int minweight, minu;
	queue<int> P;
	int *lowcost = new int[VertexNum];
	int *mst = new int[VertexNum];
	mst[0] = 0;
	//初始化
	for (int i = 1; i < VertexNum; i++)
	{
		lowcost[i] = Edges[0][i];
		mst[i] = 0;
	}

	for (int i = 1; i < VertexNum; i++)
	{
		
		minweight = MAX_Weight;//这里是1000
		minu = 0;
		for (int j = 1; j < VertexNum; j++)
		{
			if (lowcost[j] < minweight&& lowcost[j]!=0)
			{
				minweight = lowcost[j];
				minu = j;
			}
		}
		//分别push:边两个顶点的下标和边权值
		P.push(mst[minu]);
		P.push(minu);
		P.push(minweight);

		//push进的顶点置最大,表示不用更新它的权值了
		lowcost[minu] = 0;

		//如果新加入的点的权值小于之前的,则更新lowcost和mst
		for (int j = 1; j < VertexNum; j++)
		{
			if (Edges[minu][j] < lowcost[j])
			{
				lowcost[j] = Edges[minu][j];
				mst[j] = minu;
			}
		}
	}
	return P;
}

void Map::primout()
{
	queue<int> P = prim();
	while (!P.empty())
	{
		cout << P.front() << "-";
		P.pop();
		cout << P.front() << " :";
		P.pop();
		cout << P.front() << endl;
		P.pop();

	}
}
最后的输出结果如下:





扫描二维码关注公众号,回复: 2703763 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_31548387/article/details/75307456