克鲁斯卡尔算法生成最小生成树

#include<stdio.h>
#include <stdlib.h>
#define MAXD 20
#define MAXEDG 40

typedef struct{
	int pre;
	int bak;
	int weight;
}edg;

void kruscal(edg bian[],int dnum,int edgnum);
void sort(edg bain[],int edgnum);
int find(int check[],int v);

/*
变量含义说明:
bian[]:存储边的信息,pre和bak分别是两个顶点,weigt是边的权重 
MAXD:最大的顶点数的宏定义 
MAXEDG: 最大的边数的宏定义 
check[]:标记已经遍历了的顶点,避免重复遍历 
edgnum:边的数目 
dnum:顶点的数目 
*/

int main(void)
{
	edg bian[MAXEDG];
	int edgnum,dnum;
	int i,j;
	printf("请输入顶点数目:");
	scanf("%d",&dnum);
	int matrix[dnum-1][dnum-1];
	for(i=0;i<dnum;i++)
	{
		for(j=0;j<dnum;j++)
		{
			matrix[i][j]=0;
		}
	}
	printf("请输入边的数目(边的数目不能超过%d):",dnum*dnum);
	scanf("%d",&edgnum);
	printf("按(顶点 顶点 权值)的格式输入边的信息且顶点值的大小不能超过 %d\n",dnum);
	for(i=1;i<=edgnum;i++)
	{
		printf("输入第%d条边的信息(按回车键确认):",i); 
		scanf("%d %d %d",&bian[i].pre,&bian[i].bak,&bian[i].weight);
		matrix[bian[i].pre-1][bian[i].bak-1]=bian[i].weight;
	}
	printf("\n\n图的邻接矩阵为:\n");
	for(i=0;i<dnum;i++)
	{
		for(j=0;j<dnum;j++)
		{
			printf("%d ",matrix[i][j]);
		}
		printf("\n");
	}
	sort(bian,edgnum);
	printf("\n\n最小生成树的边如下所示:\n边\t权值\n");
	kruscal(bian,dnum,edgnum);
	printf("\n\n"); 
	system("pause"); 
	return 0;	
}

void kruscal(edg bian[],int dnum,int edgnum)
{
	int check[MAXD];
	int v1,v2,i,j;
	for(i=1;i<=edgnum;i++)
	check[i]=0;
	i=1;j=1;
	while(j<=edgnum&&i<=dnum-1)
	{
		v1=find(check,bian[j].pre);
		v2=find(check,bian[j].bak);
		if(v1!=v2)
		{
			printf("(%d,%d)\t%d\n",bian[j].pre,bian[j].bak,bian[j].weight);
			check[v1]=v2;
			i++;
		}
		j++;
	}
}

void sort(edg bian[],int edgnum)
{
	int i,j;
	for(i=2;i<=edgnum;i++)
	if(bian[i].weight<bian[i-1].weight)
	{
		bian[0]=bian[i];
		j=i-1;
		while(bian[0].weight<bian[j].weight)
		{
			bian[j+1]=bian[j];
			j--;
		}
		bian[j+1]=bian[0];
	}
} 

int find(int check[],int v)
{
	int i;
	i=v;
	while(check[i]>0)
	i=check[i];
	return i;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值