前言
Kruskal算法在求最小生成树上的一个典型算法
声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出
实现思想
- 将图中的权值按从小到大的顺序排列
- 按照权值大小一次选取,如果未形成回路则将其加入到数组中(保存连通信息的数组)
- 如果已经形成回路则舍弃
- 一直遍历知道连通数组中有n-1条边(最小生成树)
代码实现
#include <stdio.h>
#define Max 100
typedef struct {
int u; //边的起始顶点
int v; //边的终止顶点
int w; //权值
}Edge;
Edge E[Max];
//建立无向网的边表
int CreatEdge(){
int anum,i;
printf("\t输入无向网的边数: ");
scanf("%d",&anum);
for(i=0;i<anum;i++){
printf("v1 v2 w= ");
scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
}
return anum;
}
//边表从小到大的排序
void sort(int n){
int i,j;
Edge t;
for(i=0; i<n-1; i++){
for(j=i+1; j<n; j++){
if(E[i].w > E[j].w){
t=E[i];
E[i]=E[j];
E[j]=t;
}
}
}
}
//通过边表查看顶点所在集合
int seek(int set[],int v){
int i = v;
while(set[i] > 0)
i=set[i];
return i;
}
//E表示的图已经通过排序从小到大排列
void Kruskal(Edge E[],int n){
int set[Max]; //辅助标志数组
int V1,V2,i;
for(i = 0; i < Max; i++)
set[i]=0; //给set集合中的元素赋初值
i=0; //获取生成树的边数,初值为1
while(i < n){ //按照边的权值递增顺序,来逐边检查该边是否加入到生成树中
V1=seek(set,E[i].u); //确定顶点所在的连通集
V2=seek(set,E[i].v);
if (V1 != V2)
{
printf("(%d , %d) %d\n",E[i].u,E[i].v,E[i].w);
set[V1]=V2; //将v2加到v1集合中
}
i++;
}
}
int main(){
int n;
n=CreatEdge();
sort(n);
printf("\t最小生成树为:\n");
Kruskal(E,n);
return 0;
}
结果图
而塞过 2021-5-27
关于我:一个就要进入互联网,经历社会毒打的99小伙