最小生成树算法——Kruskal算法

这段代码展示了如何用C语言实现Kruskal算法,以构建加权无向图的最小生成树。程序首先定义了图的邻接矩阵结构,并通过直接插入排序对边进行排序。然后,应用Kruskal算法逐步选择不产生环的最小边来构建最小生成树。
摘要由CSDN通过智能技术生成

工程代码

#include <stdio.h>
#define MaxSize 20
#define INF 32767 //INF表示∞
#define MAXV 20 //最大顶点个数

typedef char InfoType;
typedef struct
{
  int no; //顶点编号
  InfoType info; //顶点其他信息
} VertexType; //顶点类型

typedef struct //图的定义
{
  int edges[MAXV][MAXV]; //邻接矩阵
  int n, e; //顶点数,弧数
  VertexType vexs[MAXV]; //存放顶点信息
} MGraph; //图的邻接矩阵类型

typedef struct
{
  int u; //边的起始顶点
  int v; //边的终止顶点
  int w; //边的权值
} Edge;

void InsertSort(Edge E[], int n) //对E[0..n-1]按递增有序进行直接插入排序
{
  int i, j;
  Edge temp;
  for (i = 1; i < n; i++) {
    temp = E[i];
    j = i - 1; //从右向左在有序区E[0..i-1]中找E[i]的插入位置
    while (j >= 0 && temp.w < E[j].w) {
      E[j + 1] = E[j]; //将关键字大于E[i].w的记录后移
      j--;
    }
    E[j + 1] = temp; //在j+1处插入E[i]
  }
}

void Kruskal(MGraph g)
{
  int i, j, u1, v1, sn1, sn2, k;
  int vset[MAXV];
  Edge E[MaxSize]; //存放所有边
  k = 0; //E数组的下标从0开始计
  for (i = 0; i < g.n; i++) //由g产生的边集E,不重复选取同一条边
    for (j = 0; j < i; j++)
      if (g.edges[i][j] != 0 && g.edges[i][j] != INF) {
        E[k].u = i;
        E[k].v = j;
        E[k].w = g.edges[i][j];
        k++;
      }

  InsertSort(E, g.e); //采用直接插入排序对E数组按权值递增排序

  for (i = 0; i < g.n; i++) //初始化辅助数组
    vset[i] = i;
  k = 1; //k表示当前构造生成树的第几条边,初值为1
  j = 0; //E中边的下标,初值为0
  while (k < g.n) //生成的边数小于n时循环
  {
    u1 = E[j].u;
    v1 = E[j].v; //取一条边的头尾顶点
    sn1 = vset[u1];
    sn2 = vset[v1]; //分别得到两个顶点所属的集合编号
    if (sn1 != sn2) //两顶点属于不同的集合,该边是最小生成树的一条边
    {
      printf("  (%d,%d):%d\n", u1, v1, E[j].w);
      k++; //生成边数增1
      for (i = 0; i < g.n; i++) //两个集合统一编号
        if (vset[i] == sn2) //集合编号为sn2的改为sn1
          vset[i] = sn1;
    }
    j++; //扫描下一条边
  }
}

int main()
{
  int i, j;
  MGraph g;
  g.n = 5;
  g.e = 7;
  int a[MAXV][MAXV] = {
      {0,   1,   INF, INF, 7},
      {1,   0,   6,   INF, 5},
      {INF, 6,   0,   3,   4},
      {INF, INF, 3,   0,   2},
      {7,   5,   4,   2,   0}
  };

  for (i = 0; i < g.n; i++) //建立图的邻接矩阵
    for (j = 0; j < g.n; j++)
      g.edges[i][j] = a[i][j];
  printf("最小生成树构成:\n");
  Kruskal(g);
  printf("\n");
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值