特点:适用于稀疏图,边比较少的图。如果顶点较少,且为稠密图,则用Prim算法。跟Prim算法的用途相同。时间复杂度为O(e*loge),其中e为边数。
代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXEDGE 20 //设定边的最大值
#define INF 65535 //用来设定边的最大值
typedef struct Edge
{
int begin;
int end;
int weight;
}Edge; //构建的边结点
typedef struct EGraph
{
Edge edge[MAXEDGE];
Edge EdgeSorted[MAXEDGE];
int numGraphEdge;
}EGraph; //构建的边集数组结构
static int Flag[MAXEDGE]; //定义排序时各个顶点是否被比较过的状态,如果被比较过赋给EdgeSorted后,Flag = 1
void CreateEGraph(EGraph *G) //构建一个操作的图
{
int i = 0,j = 0,k = 0,w = 0;
printf("请输入图中边的数目:\n");
scanf("%d",&G->numGraphEdge);
for(k = 0;k < G->numGraphEdge;k++)
{
printf("请输入边vi-vj的边的下标 i 和 j ,以及权重w :\n");
scanf("%d,%d,%d",&i,&j,&w);
G->edge[k].begin = i;
G->edge[k].end = j;
G->edge[k].weight = w;
}
for(k = 0;k < G->numGraphEdge;k++) //初始化标示数组
{
Flag[k] = 0;
}
}
void SortEdge(EGraph *G) //对边集数组按权值大小进行排序
{
int min,k,i,j;
for(i = 0;i < G->numGraphEdge;i++)
{
min = INF;
for(j = 0;j < G->numGraphEdge;j++)
{
if(Flag[j] == 0 && min >= G->edge[j].weight)
{
min = G->edge[j].weight;
k = j;
}
}
Flag[k] = 1;
G->EdgeSorted[i].begin = G->edge[k].begin;
G->EdgeSorted[i].end = G->edge[k].end;
G->EdgeSorted[i].weight = G->edge[k].weight;
}
printf("\n*******************************\n");
printf("排序后的权值依次为:\n");
for(i = 0;i < G->numGraphEdge;i++)
{
printf("%d ",G->EdgeSorted[i].weight);
}
}
int Find(int *parent,int f) //构造parent数组,为了判断最小生成树中是否构成了回路
{
while(parent[f] > 0) //注意必须是while循环,直到parent[f]中的值为0,返回parent数组下标f
{
f = parent[f];
}
return f;
}
//kurskal算法:依次遍历被排好序的边集数组,如果没有构成回路,就把他加入最小生成树,如果构成回路,则无视继续循环
void Kruskal(EGraph *G)
{
int i = 0,m,n;
int parent[MAXEDGE];
for(i = 0;i < G->numGraphEdge;i++)
{
parent[i] = 0;
}
for(i = 0;i < G->numGraphEdge;i++)
{
m = Find(parent,G->EdgeSorted[i].begin);
n = Find(parent,G->EdgeSorted[i].end);
if(m != n) //说明没有形成环路
{
parent[m] = n;
printf("(%d,%d,%d) ",G->EdgeSorted[i].begin,G->EdgeSorted[i].end,G->EdgeSorted[i].weight);
}
}
}
int main()
{
EGraph G; //声明一个图
CreateEGraph(&G); //创建图
SortEdge(&G);
printf("\n*******************************\n");
printf("\nkurskal得到的最小生成树的边为:\n");
Kruskal(&G); //打印由kurskal算法得到的最小生成树的各个边
printf("\n\n*******************************\n");
return 0;
}