系列文章目录
深度优先算法 DFS
广度优先算法 BFS
Prim算法
Kruskal算法
Dijkstra算法
系列文章将会写图的经典的几种,有错误的地方欢迎在评论中提出。
文章目录
前言
提示:Prim算法和Kruskal算法是为了实现图中的最小生成树的算法。不同的是,Prim算法从节点上开始入手,而Kruskal算法是从边上入手,各有优劣。
提示:以下是本篇文章正文内容,下面案例可供参考
一、 Kruskal算法简介
Kruskal算法的从最小的边开始,将其连接成一个生成树,并在连接时判断是否在一个生成树上,直到遍历了n-1条边。
该处使用的url网络请求的数据。
二. Kruskal算法的代码实现(c语言)
代码如下(示例):
1. Kruskal算法的部分
void spantree_kruskal(graphmtx *g)
{
edge *e=(edge *)malloc(sizeof(edge)*g->numedge);
int n=0;
for(int i=0;i<g->numvertice;i++)
{
for(int j=i+1;j<g->numvertice;j++)
{
if(g->edge[i][j]!=max)
{
e[n].x=i;
e[n].y=j;
e[n++].cost=g->edge[i][j];
}
}
}
for(i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(e[j].cost>e[j+1].cost)
{
swap(e[j],e[j+1]);
}
}
}
/* for(i=0;i<n;i++)
{
printf("%d-->%d:%d",e[i].x,e[i].y,e[i].cost);
printf("\n");
}
*/
int father[max];
for(i=0;i<g->numvertice;i++)
{
father[i]=i;
}
int x,y,cnt=0,k=0;
while(cnt<g->numvertice-1)
{
x=getfather(e[k].x,father);
y=getfather(e[k].y,father);
if(x!=y)
{
father[x]=y;
cnt++;
printf("%c-->%c:%d",g->verticelist[e[k].x],g->verticelist[e[k].y],e[k].cost);
printf("\n");
}
//printf("%c-->%c:%d",g->verticelist[e[k].x],g->verticelist[e[k].y],e[k].cost);
//printf("%d-->%d:%d",e[k].x,e[k].y,e[k].cost);
k++;
}
}
2.全部代码
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define defaultnum 10
#define t char
#define max 100
typedef struct graphmtx
{
int maxvertice;
int numvertice;
int numedge;
t *verticelist;
int **edge;
}graphmtx;
typedef struct edge
{
int x;
int y;
int cost;
}edge;
void initgraph(graphmtx *g);
void showgraph(graphmtx *g);
void insertvertice(graphmtx *g,t e);
int findpos(graphmtx *g,t e);
void insertedge(graphmtx *g,t e1,t e2,int cost);
void spantree_kruskal(graphmtx *g);
void swap(edge &e1,edge &e2);
int getfather(int x,int *father);
void main()
{
graphmtx gm;
initgraph(&gm);
insertvertice(&gm,'A');
insertvertice(&gm,'B');
insertvertice(&gm,'C');
insertvertice(&gm,'D');
insertvertice(&gm,'E');
insertvertice(&gm,'F');
insertvertice(&gm,'G');
insertedge(&gm,'A','B',19);
insertedge(&gm,'A','E',14);
insertedge(&gm,'A','G',18);
insertedge(&gm,'C','B',5);
insertedge(&gm,'E','B',12);
insertedge(&gm,'D','B',7);
insertedge(&gm,'E','D',8);
insertedge(&gm,'C','D',3);
insertedge(&gm,'D','F',21);
insertedge(&gm,'G','F',27);
insertedge(&gm,'E','G',16);
showgraph(&gm);
printf("\n");
spantree_kruskal(&gm);
}
void initgraph(graphmtx *g)
{
g->maxvertice=defaultnum;
g->numedge=g->numvertice=0;
g->verticelist=(t*)malloc(sizeof(t)*defaultnum);
assert(g->verticelist !=NULL);
g->edge=(int **)malloc(sizeof(int *)*defaultnum);
assert(g->edge!=NULL);
for(int i=0;i<g->maxvertice;++i)
{
g->edge[i]=(int *)malloc(sizeof(int)*defaultnum);
}
for(i=0;i<g->maxvertice;++i)
{
for(int j=0;j<g->maxvertice;++j)
{
if(i==j)
g->edge[i][j]=0;
else
g->edge[i][j]=max;
}
}
}
void showgraph(graphmtx *g)
{
printf(" ");
for(int i=0;i<g->numvertice;i++)
printf("%c ",g->verticelist[i]);
printf("\n");
for(i=0;i<g->numvertice;i++)
{
printf("%c ",g->verticelist[i]);
for(int j=0;j<g->numvertice;j++)
{
if(g->edge[i][j]==max)
printf("@ ");
else
{
printf("%d ",g->edge[i][j]);
}
}
printf("\n");
}
printf("\n");
}
void insertvertice(graphmtx *g,t e)
{
if(g->numedge>g->numvertice)
{
printf("已满");
return;
}
g->verticelist[g->numvertice++]=e;
}
int findpos(graphmtx *g,t e)
{
for(int i=0;i<g->numvertice;i++)
{
if(g->verticelist[i]==e)
return i;
}
return -1;
}
void insertedge(graphmtx *g,t e1,t e2,int cost)
{
int p=findpos(g,e1);
int w=findpos(g,e2);
if(p==-1||w==-1)
return;
if(g->edge[p][w]!=max)
return;
g->edge[p][w]=g->edge[w][p]=cost;
}
void spantree_kruskal(graphmtx *g)
{
edge *e=(edge *)malloc(sizeof(edge)*g->numedge);
int n=0;
for(int i=0;i<g->numvertice;i++)
{
for(int j=i+1;j<g->numvertice;j++)
{
if(g->edge[i][j]!=max)
{
e[n].x=i;
e[n].y=j;
e[n++].cost=g->edge[i][j];
}
}
}
for(i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(e[j].cost>e[j+1].cost)
{
swap(e[j],e[j+1]);
}
}
}
/* for(i=0;i<n;i++)
{
printf("%d-->%d:%d",e[i].x,e[i].y,e[i].cost);
printf("\n");
}
*/
int father[max];
for(i=0;i<g->numvertice;i++)
{
father[i]=i;
}
int x,y,cnt=0,k=0;
while(cnt<g->numvertice-1)
{
x=getfather(e[k].x,father);
y=getfather(e[k].y,father);
if(x!=y)
{
father[x]=y;
cnt++;
printf("%c-->%c:%d",g->verticelist[e[k].x],g->verticelist[e[k].y],e[k].cost);
printf("\n");
}
//printf("%c-->%c:%d",g->verticelist[e[k].x],g->verticelist[e[k].y],e[k].cost);
//printf("%d-->%d:%d",e[k].x,e[k].y,e[k].cost);
k++;
}
}
void swap(edge &e1,edge &e2)
{
int x=e1.x;
int y=e1.y;
int cost=e1.cost;
e1.x=e2.x;
e1.y=e2.y;
e1.cost=e2.cost;
e2.x=x;
e2.y=y;
e2.cost=cost;
}
int getfather(int x,int *father)
{
if(x!=father[x])
father[x]=getfather(father[x],father);
return father[x];
}
代码实现结果如下