#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <queue>
#define NUM 6
#define MAXSIZE 30
using namespace std;
//定义并查集树
typedef struct UNode
{
int data;
int rank;
int parent;
} UNode,UFSTree;
//定义邻接矩阵
typedef struct Node
{
int num;
int data;
} Node;
typedef struct MGraph
{
int edges[NUM][NUM];
int n,e;
} MGraph;
//定义边
typedef struct Edge
{
int u;//起点
int v;//终点
int w;//权值
bool operator < (const Edge &a) const
{
return w > a.w;
}
} Edge;
MGraph *build_graph();
void kruskal(MGraph *mgraph);
void MAKE_SET(UFSTree t[], int n);
int FIND_SET(UFSTree t[], int x);
void UNION(UFSTree t[], int x, int y);
int main(void )
{
MGraph *mgraph;
mgraph=build_graph();
kruskal(mgraph);
return 0;
}
MGraph *build_graph()
{
MGraph *mgraph;
int i,j;
int this_edges=0;
int arrays[NUM][NUM]={{0,6,1,5,INT_MAX,INT_MAX},
{6,0,5,INT_MAX,3,INT_MAX},
{1,5,0,5,6,4},
{5,INT_MAX,5,0,INT_MAX,2},
{INT_MAX,3,6,INT_MAX,0,6},
{INT_MAX,INT_MAX,4,2,6,0}};
mgraph=(MGraph *)malloc(sizeof(MGraph));
for(i=0;i<NUM;i++)
{
for(j=0;j<NUM;j++)
{
mgraph->edges[i][j]=arrays[i][j];
if(arrays[i][j]!=0 && arrays[i][j]!=INT_MAX)
{
this_edges++;
}
}
}
mgraph->n=NUM;
mgraph->e=this_edges;
//测试生成的邻接矩阵
printf("node=%d,edges=%d\n",mgraph->n,mgraph->e);
for(i=0;i<NUM;i++)
{
for(j=0;j<NUM;j++)
{
if(mgraph->edges[i][j]!=INT_MAX)
{
printf("%3d",mgraph->edges[i][j]);
}
else
{
printf("%3c",'&');
}
}
printf("\n");
}
return mgraph;
}
//Kruskal算法
void kruskal(MGraph *mgraph)
{
int i,j;
int k; // 存储已并入的边数
int u1,v1; // 存储当前最小边
int sn1,sn2; // 存储两个顶点所属集合
UFSTree t[MAXSIZE]; // 存储并查集树
Edge E[MAXSIZE]; // 存储所有的边
priority_queue<Edge> pq; // 优先队列,每次弹出最小边
//把所有边存入优先队列
k=1;
for(i=0;i<mgraph->n;i++)
{
for(j=0;j<=i;j++)
{
if(mgraph->edges[i][j]!=0 && mgraph->edges[i][j]!=INT_MAX)
{
E[k].u=i;
E[k].v=j;
E[k].w=mgraph->edges[i][j];
pq.push(E[k]);
}
}
}
MAKE_SET(t,mgraph->n); // 初始化并查集
//每次选出最小边并入
k=1;
while(k<mgraph->n)
{
u1=pq.top().u;
v1=pq.top().v;
sn1=FIND_SET(t,u1);
sn2=FIND_SET(t,v1);
if(sn1!=sn2)
{
printf("%d-%d: %d\n",u1,v1,pq.top().w);
k++;
UNION(t,u1,v1);
}
pq.pop();
}
}
//初始化并查集
void MAKE_SET(UFSTree t[], int n)
{
int i;
for(i=0;i<n;i++)
{
t[i].data=i;
t[i].rank=0;
t[i].parent=i;
}
}
//并查集查找
int FIND_SET(UFSTree t[], int x)
{
if(x!=t[x].parent)
return FIND_SET(t,t[x].parent);
else
return x;
}
//并查集合并
void UNION(UFSTree t[], int x, int y)
{
x=FIND_SET(t,x);
y=FIND_SET(t,y);
if(t[x].rank > t[y].rank)
t[y].parent=x;
else
{
t[x].parent=y;
if(t[x].parent==t[y].parent)
t[y].rank++;
}
}
Kruskal算法实现
最新推荐文章于 2021-03-25 19:25:25 发布