不同于克里姆算法,是以顶点为根出发进行查找路径,克鲁斯卡尔算法是通过最短边来查找路径。
只不过这次存储结构是用边表结构,并且按照权重升序来存储。
图还是和上一篇Prim算法里的一样:
边表存储结构:
完整代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXVEX 9
typedef struct
{
int begin;
int end;
int weight;
} EdgeNode;
typedef struct
{
int numVertex, numEdge;
EdgeNode Edge[15];
} EGraph;
void CreateGraph(EGraph *G)
{
int i;
printf("请输入顶点数目:");
scanf("%d", &G->numVertex);
printf("请输入边的数目:");
scanf("%d", &G->numEdge);
printf("按照权值升序输入起始顶点、结束顶点和权值:\n");
for (i = 0; i < G->numEdge; i++)
{
scanf("%d,%d %d", &G->Edge[i].begin, &G->Edge[i].end, &G->Edge[i].weight);
}
}
void MiniSpanTree_Kruskal(EGraph *G)
{
int i, n, m;
int parent[MAXVEX];
for (i = 0; i < G->numVertex; i++)
parent[i] = 0;
//对图中的每一条边进行循环
for (i = 0; i < G->numEdge; i++)
{
n = Find(parent, G->Edge[i].begin);
m = Find(parent, G->Edge[i].end);
if (m != n) //m如果等于n,说明是环路,最小生成树里不能出现环路
{
parent[n] = m;
printf("(%d, %d) %d\n", G->Edge[i].begin, G->Edge[i].end, G->Edge[i].weight);
}
}
}
//查找连线顶点的尾部下标
int Find(int *parent, int f)
{
while (parent[f] > 0)
f = parent[f];
return f;
}
int main()
{
EGraph G;
CreateGraph(&G);
MiniSpanTree_Kruskal(&G);
return 0;
}
程序运行结果:
- 输入图信息
- 输出最小生成树边