最小生成树的两种方法Prim和Kruskal(C++)

本文介绍了最小生成树问题,重点讲解了Prim和Kruskal两种算法的C++实现。Prim算法通过邻接矩阵找到最短边并逐步构建最小生成树,而Kruskal算法则需要先对边进行排序,然后依次选择不形成环的最短边加入树中。这两种方法都是解决无向连通图中找寻最小生成树的经典算法。
摘要由CSDN通过智能技术生成

最小生成树的两种方法Prim和Kruskal(C++)

最小生成树:n个顶点用n-1条最短的边连起来且不重复。
Prim算法——基本思想
图采用邻接矩阵存储
数组adjvex[n]:表示候选最短边的邻接点
数组lowcost[n]:表示候选最短边的权值

算法:Prim 输入:无向连通网G=(V,E) 输出:最小生成树T=(U,TE)

  1. 初始化:U = {v}; TE={ };
  2. 重复下述操作直到U = V:
    2.1 在E中寻找最短边(i,j),且满足i∈U,j∈V-U;
    2.2 U = U + {j};
    2.3 TE = TE + {(i,j)};
void Prim(int v)   //从顶点v出发
{
      
	int i, j, k;
	int adjvex[MaxSize], lowcost[MaxSize];
    for (i = 0; i < vertexNum; i++)    //初始化辅助数组
	{
       // 先把与v相邻的边赋值到lowcost中, 在lowcost中寻找最短边 
		lowcost[i] = edge[v][i]; adjvex[i] = v;
	}
	lowcost[v] = 0;                //将顶点v加入集合U,lowcost[i]=0;表示将其加入到U中 U={v,i} 
	for (k = 1; k < vertexNum; k++)   //迭代n-1次
	{
   
		j = MinEdge(lowcost, vertexNum);//寻找最短边的邻接点j 
      	cout << "(" << vertex[j] << "," << vertex[adjvex[j]] << ")" << lowcost[j] << endl; 
		lowcost[j] = 0;                 //顶点j加入集合U,本身到本身的距离为0 
		for (i = 0; i < vertexNum; i++) //调整辅助数组
	        if (edge[i][j] < lowcost[i]) {
    //将j[新增点]的相连边的距离更新到lowcost 
				lowcost[i] = edge[i][j]; 
				adjvex[i] = j;
        	}
    }
}

Kruskal算法
【注意先对边集合edge[i]进行排序,让最短边先开始Kruskal】
【这是个坑,不然会按照你输入边的顺序进行Kruskal】

算法:Kruskal算法 输入:无向连通网G=(V,E) 输出:最小生成树T=(U,TE)
1. 初始化:U=V;TE={ };
2. 重复下述操作直到所有顶点位于一个连通分量:
2.1 在E中选取最短边(u,v);
2.2 如果顶点 u、v 位于两个连通分量,则
2.2.1 将边 (u,v) 并入TE;
2.2.2 将这两个连通分量合成一个连通分量;
2.3 在 E 中标记边 (u,v),使得 (u,v) 不参加后续最短边的选取;

void Kruskal( )
{
   
	int num = 0, i, vex1, vex2;
	int parent[vertexNum];                   //双亲表示法存储并查集
	for (i = 0; i < vertexNum; i++)
  		parent[i] = -1;                      //初始化n个连通分量
	for (num = 0, i = 0; num < vertexNum - 1; i++)//依次考察最短边
	{
   
  		vex1 = FindRoot(parent, edge[i].from);
  		vex2 = FindRoot(parent, edge[i].to);
  		if (vex1 != vex2) {
                     //位于不同的集合
    		cout << "(" << vertex[edge[i].from]<< "," << vertex[edge[i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值