数据结构之生成最小树

这里主要讲了两个算法。

首先说明下,本文讲到的两个算法都是和连接矩阵和连接表没有关系的,因为每个算法开始的时候,都会有一个初始化代码,经过初始化后,最后都会变成统一的算法语句。

我们这里会介绍两种算法,第一种算法,Prim算法。这个算法,内容就是加点法,可以理解为在U集合周围找到权值最小的边的点,添加到U集合上,使得最后所有的点都在U集合上。

算法思想:

假设N=(V, E)是连通网,TE是N上最小生成树中边的集合。算法如下: (1)初始时,U={u},TE=φ; (2)在所有<u, v>∈E(u∈U,v∈V-U)的边中选一条代价最小的边(u, v)并入集合TE,同时将v并入U; (3)重复(2),直到U=V为止。此时,TE中必含有n-1条边,则T=(V, TE)为N的最小生成树。 可以看出,普利姆算法是逐步增加U中的顶点,称为“加点法”。 但请注意:在选择最小边时,可能有多条权值相等的边可选,此时任选其一。


代码如何实现这个Prime算法,事实上也就是四个步骤.

初始化

找到一个最小的权值的点(在哪里找?在lowCost里面找)

将其加入U集合中

修改lowCost和parent数组

我们这里分别来讲:
初始化

        int sum,k;
	int lowCost[vertexNum],parent[vertexNum];
	k=locate(g,u);
	int n=g->vertexNum;
	for(int i=0;i<n;i++){
		lowCost[i]=g->edge[k][i];
		parent[i]=k;
	}
	parent[k]=-1;
	lowCost[k]=0;//也就是用连接矩阵,设置好lowCost数组和parent数组
找到一个最小的权值的点
k=findMin(lowCost,n);
修改lowCost和parent数组
for(int j=0;j<n;j++){
    if(g->edge[k][j]<lowCost[j] && lowCost[j]!=0){
        lowCost[j]=g->edge[k][j];
        parent[j]=k;
    }
}

总的代码:
void Prim(Graph g,int u)
{
	int sum,k;
	int lowCost[vertexNum],parent[vertexNum];
	k=locate(g,u);
	int n=g->vertexNum;
	for(int i=0;i<n;i++){
	    lowCost[i]=g->edge[k][i];
	    parent[i]=k;
	}
	parent[k]=-1;
	lowCost[k]=0;
	sum=0;
	for(int i=1;i<n;i++){//注意是查询n-1次。 
		k=findMin(lowCost,n);//这个函数就是一个简单的从一个数组中找到最小的值,所在的下标,并且返回回来。
		if(k==-1){
			return ;
		}
		sum=sum+lowCost[k];
		lowCost[k]=0;
		for(int j=0;j<n;j++){
			if(g->edge[k][j]<lowCost[j] && lowCost[j]!=0){
				lowCost[j]=g->edge[k][j];
				parent[j]=k;
			}
		}
	}
	return sum;
}
Krus算法,其实这个也就是一个并查集算法,我这里先把代码放出来。
void Krus(Graph g)
{
	int i,j,n;
	Edge edges[vertexNum*vertexNum];
	sort(edges);
	for(int i=0;i<g->edges;i++){
		n=find(edges[i].begin);
		m=find(edges[i].end);
		if(n!=m){
			parent[n]=m;
		} 
	}
} 

其中的find函数在这里

int find(int parent[],int x)  
{  
    while(parent[x]!=x){  
        x=parent[x];  
    }   
    return x;  
}   

先写到这里,以后来完善



猜你喜欢

转载自blog.csdn.net/qq_41861526/article/details/80532450
今日推荐