浅谈最小(代价)生成树(普利姆算法和克鲁斯卡尔算法)

一、普利姆算法

1、算法思想

       从图中任选一个顶点,把它当作一棵树,然后从与这棵树相接的边中选取一条权值最小的边,并将这条边及其所连接的顶点并入这棵树中,此刻就得到了一棵有三个顶点的树。然后从与这棵树相接的边中任选一条权值最小的边,将这条边及其所连接的顶点并入这棵树中,依次类推,直到图中所有的顶点都被并入树中为止,此时所得的树就是最小生成树
       例如,图 1-1a所示的带权无向图采用普利姆算法求解最小生成树的过程如
图 1-1b~1-1e所示,以顶点0为起点,生成树过程如下:
       1)如图1-1a所示,与顶点0相接的三条边的权值分别为5、1、2,最小边权值为1;
       2)如图1-1b所示,选择权值为1的边,此时候选边的权值分别为5、3、2、6和2,最小边权值为2;
       3)如图1-1c所示,选择权值为2的边,此时候选边的权值分别为5、3、2和3,最小边权值为2;
       4)如图1-1d所示,选择权值为2的边,此时候选边的权值分别为5、3和4,最小边权值为3;
       5)如图1-1e所示,选择权值为3的边,此时所有的顶点都已并入生成树中,最小生成树求解过程完毕。

2、普利姆算法执行过程

       用普利姆算法构造最小生成树的过程中,需要建立两个数组vist[]和lowcost[]。当vist[i] = 1时,表示顶点i已经被并入生成树中,vist[i] = 0表示顶点i还未被并入生成树中。lostcost[]数组中存放当前生成树到剩余顶点最短边的权值。
       执行过程如下:
       1)将顶点v0到其他顶点的所有边作为侯选边。
       2)重复以下步骤n - 1次,使得其他n - 1个顶点被并入到生成树中。
       I 从侯选边中挑选权值最小的边输出,并将与该边另一端相接的顶点v并入到生成树中;
       II 查看所有剩余顶点vi,如果(v,vi)的权值比lowcost[vi]小,则用
(v,vi)的权值更新lowcost[vi]。

void Prim(MG g ,int v0,int &sum)
{
	int lowcost[maxSize], vist[maxSize], v;
	int i , j , k , min;
	v = v0;
	for(i = 0;i < g.n;i++){
		lowcost[i] = g.edges[v0][i];
		vist[i] = 0;
	}
	vist[v0] = 1;
	sum = 0;
	for(i = 0;i<g.n - 1;++i){
		min = INF;
		for(j = 0 ;j<g.n; ++j){
			if(vist[j] == 0&&lowcost[j]<min){
					min = lowcost[j];
					k = j;
			}
		}
		vist[k] = 1;
		v = k;
		sum += min;
		for(j = 0 ; j<g.n;++j){
			if(vist[j] ==0 &&g.edges[v][j]<lowcost[j]){
				lowcost[j] = g.edges[v][j];
			}
		}
	}
}

二、克鲁斯卡尔算法

1、算法思想

       每次找出侯选边中权值最小的边,就把该边并入生成树中,重复此过程,直到所有边都被检测完为止。

2、执行过程

typedef struct
{
	int a,b;
	int w;
}Road;
Road road[maxSize];
int v[maxSize];
int getRoot(int a ){
	while(a != v[a] ) 
	 	a = v[a];
	 return a; 
}
void Kruskal(MG g,int &sum,Road road[]){
	int i;
	int N,E,a,b;
	N = g.n;
	E = g.e;
	sum = 0;
	for(i = 0 ; i<N;++i)
		v[i] = i;
	sort(road,E);
	for(i = 0;i<E;++i){
		a = getRoot(road[i].a);
		b = getRoot(road[i].b);
		if(a != b){
			v[a] = b;
			sum += road[i].w;
		}
	}
}

三、两种算法的比较

1、普利姆算法时间复杂度为O(n^2),普利姆算法的时间复杂度只与图中顶点有关系,与边数没有关系,因此普利姆算法适用于稠密图; 克鲁斯卡尔算法时间主要花费在sort()函数上,因此克鲁斯卡尔算法的时间复杂度主要由选取的排序算法决定,排序算法所处理数据的规模由图的边数决定,与顶点数无关,因此克鲁斯卡尔算法适用于稀疏图;
2、普利姆算法和克鲁斯卡尔算法都是针对于无向图。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值