您的位置:首页 > 其它

最小生成树--Kruskal算法

2016-04-19 17:22 369 查看
与Prim算法不同,Kruskal算法基于并查集和贪心算法,利用并查集判断其是否存在循环。

Kruskal算法基本思想: 对所有边进行排序,优先选取权重小的边,并同时判断其是否联通(利用并查集判断)
数据结构:结构体数组
算法思想:快排,贪心,递归

用结构体来储存边

typedef struct edge{
int u;//顶点
int v;//末点
int w;//权重
}EDGE;
EDGE e[100];


利用快排排序:

void sort(int left,int right)
{
int i,j;
EDGE t;
if(left>right)
return ;
i=left;
j=right;
while(i!=j)
{
while(e[j].w>=e[left].w&&i<j)   j--;
while(e[i].w<=e[left].w&&i<j)   i++;
if(i<j)
{
t=e[i];
e[i]=e[j];
e[j]=t;
}
}

t=e[i];
e[i]=e[left];
e[left]=t;

sort(left,i-1);
sort(i+1,right);
return ;
}


利用并查集来判断是否是形成联通环:

int merge(int x,int y)
{
int i=getf(x);
int j=getf(y);
if(i!=j)//如果不相同则利用偏左原则
{
f[j]=i;//把祖宗更变
return 1;
}
else
return 0;
}
int getf(int v)//利用递归找祖先
{
if(v==f[v])
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}

最后利用贪心把边一条条符合条件的边放入集合中:

for(i=1;i<=m;i++)
{
if(merge(e[i].u,e[i].v))
{
sum+=e[i].w;//如果不在一个集合中,则把边放入
count++;//计数器
}
if(count==n-1)
break;
}


来看全部代码的实现:

#include<stdio.h>
#include<string.h>
#include<conio.h>
int f[100];
int n,m,sum,count;
typedef struct edge{ int u;//顶点 int v;//末点 int w;//权重 }EDGE; EDGE e[100];

int getf(int v);
void sort(int left,int right);
int merge(int x,int y);
int main()
{
int i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++) f[i]=i;//初始化并查集
for(i=1;i<=m;i++)
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
sort(1,m);
for(i=1;i<=m;i++)
{
if(merge(e[i].u,e[i].v))
{
sum+=e[i].w;//如果不在一个集合中,则把边放入
count++;//计数器
}
if(count==n-1)
break;
}
printf("%d",sum);
return 0;
}

void sort(int left,int right) { int i,j; EDGE t; if(left>right) return ; i=left; j=right; while(i!=j) { while(e[j].w>=e[left].w&&i<j) j--; while(e[i].w<=e[left].w&&i<j) i++; if(i<j) { t=e[i]; e[i]=e[j]; e[j]=t; } } t=e[i]; e[i]=e[left]; e[left]=t; sort(left,i-1); sort(i+1,right); return ; }
int merge(int x,int y)
{
int i=getf(x);
int j=getf(y);
if(i!=j)//如果不相同则利用偏左原则
{
f[j]=i;//把祖宗更变
return 1;
}
else
return 0;
}
int getf(int v)//利用递归找祖先
{
if(v==f[v])
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}


其实这个算法和prim算法中,都包含了贪心算法的思想,只是实现的方式不同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: