库鲁斯卡尔(Kruskal)算法是一种按照连通网中边的权值递增的顺序构造最小生成树的方法。Kruskal算法的基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点自成一个连通分量。在E中选择权值最小的边,若该边依附的顶点落在T中不同的连通分量中,则将此边加入到T中;否则,舍去此边而选下一条权值最小的边;依次类推,直到T中所有顶点都在同一个连通分量上(此时含有n-1边)为止,这时的T就是一棵最小的生成树。
    注意,初始时T的连通分量为顶点个数n,在每一次选取最小权值的边加入到T时一定要保证T的连通分量减1;也即选取最小权值边所连接的两个顶点必须位于不同的连接分量上,否则应舍去此边而再选取下一条最小权值的边。
 
    概述
    实现Kruskal算法的关键是如何判断所选取的边是否与生成树中已保留的边形成回路,这可通过判断边的两个顶点所在的连通分量的方法来解决.为此设置一个辅助数组vest(数组元素下标为0~n-1),它用于判断两个顶点集合(即两个连通分量),此时按其中的一个集合编号重新统一编号(即合并成一个连通分量)。因此,当两个顶点的集合(连通分量)编号不同时,则加入这两个顶点所构成的边到最小生成树中就一定不会形成回路,因为这两个顶点分属于不同的连通分量。
    在实现Kruskal算法时,需要用一个数组E来存放图G中是所有边,并要求他们是按权值由小到大的顺序排列的;为此先从图G的邻接矩阵中获取所有边集E(注意,在连接矩阵中顶点i和顶点j存在着(i,j)和(j,i)两条边,故只取i<j时的一条边,然后用冒泡排序法对边集E按权值递增排序。
参考代码:

 #include<stdio.h>
#define MAXSIZE 30
#define MAXCOST 32767 typedef struct
{
int u;//边的起始顶点
int v;//边的起始终点
int w;//边的权值
}Edge; void Bubblesort(Edge R[],int e)//冒泡排序,对数组R中的e条边按权值递增排序
{
Edge temp;
int i,j,swap;
for(i=;i<e-;j++)//进行e-1趟排序
{
swap=;
for(j=;j<e-i-;j++)
if(R[j].w>R[j+].w)
{
temp=R[j];R[j]=R[j+];R[j+]=temp;//交换R[j]和R[j+1]
swap=;//置有交换标志
}
if(swap==) break;//本趟比较中未出现交换则结束排序
}
} void Kruskal(int gm[][],int n)//在顶点为n的连接图中构造最小的生成树,gm为连通网的邻接矩阵
{
int i,j,u1,v1,sn1,sn2,k;
int vest[MAXSIZE];//数组vest用于判断两顶点之间是否连通
Edge E[MAXSIZE];//MAXSIZE为可存放边数的最大常量值
k=;
for(i=;i<n;i++)
for(j=;j<n;j++)
if(i<j&&gm[i][j]!=MAXCOST)//MAXCOST为一个极大的常量值
{
E[k].u=i;
E[k].v=j;
E[k].w=gm[i][j];
k++;
}
Bubblesort(E,k);//采用冒泡排序对数组E中的k条边按权值递增排序
for(i=;i<n;i++)//初始化辅助数组
vest[i]=i;//给每个顶点置不同连通分量编号,即初始时有n个连通分量
k=;//k表示当前构造生成树的第n条边,初始值为1
j=;//j为数组E中元素的下标,初值为0
while(k<n)//产生最小生成树的n-1条边
{
u1=E[j].u;v1=E[j].v;//取一条边的头尾顶点
sn1=vest[u1];
sn2=vest[v1];//分别得到这两个顶点所属的集合编号
if(sn1!=sn2)//两顶点分属于不同集合则该边为最小生成树的一条边
{
printf("Edge:(%d,%d),Wight:%d\n",u1,v1,E[j].w);
k++;//生成的边数增1
for(i=;i<n;i++)//两个集合统一编号
if(vest[i]==sn2)//集合编号为sn2的第i号边其边号改为sn1
vest[i]=sn1;
}
j++;//扫描下一条边
}
}
void main()
{
int g[][]={{,,,,,},{,,,,,},{,,,,,},
{,,,,,},{,,,,,},{,,,,,}};
Kruskal(g,);//生成最小生成树
}

输出结果:

数组E示意图:

执行Kruskal算法中的冒泡排序函数BubbleSort后,存放连通网中所有边的数组E如下图所示。因数组E中前4条边的权值最小且又满足不在同一连通分量上的条件,故它们就是生成树的边(见图a,b,c,d)。接着考虑当前权值最小边(0,3)因该边所连接的两顶点在同一连通分量上,故舍弃此边,然后再选择下一权值最小的边。这时k值已等于n(即已找到n-1条边),故终止while循环的执行。因此,最终生成树如图所示:

最小生成树的Kruskal算法的更多相关文章

  1. 最小生成树的Kruskal算法实现

    最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V ...

  2. 数据结构与算法--最小生成树之Kruskal算法

    数据结构与算法--最小生成树之Kruskal算法 上一节介绍了Prim算法,接着来看Kruskal算法. 我们知道Prim算法是从某个顶点开始,从现有树周围的所有邻边中选出权值最小的那条加入到MST中 ...

  3. 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

    matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...

  4. HDU1875——畅通工程再续(最小生成树:Kruskal算法)

    畅通工程再续 Description相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当 ...

  5. 23最小生成树之Kruskal算法

    图的最优化问题:最小生成树.最短路径 典型的图应用问题 无向连通加权图的最小生成树 有向/无向加权图的最短路径 四个经典算法 Kruskal算法.Prim算法---------------最小生成树 ...

  6. 算法学习记录-图——最小生成树之Kruskal算法

    之前的Prim算法是基于顶点查找的算法,而Kruskal则是从边入手. 通俗的讲:就是希望通过 边的权值大小 来寻找最小生成树.(所有的边称为边集合,最小生成树形成的过程中的顶点集合称为W) 选取边集 ...

  7. 图论之最小生成树之Kruskal算法

    Kruskal算法,又称作为加边法,是配合并查集实现的. 图示: 如图,这是一个带权值无向图我们要求它的最小生成树. 首先,我们发现在1的所有边上,连到3的边的边权值最小,所以加上这条边. 然后在3上 ...

  8. 【最小生成树之Kruskal算法】

    看完之后推荐再看一看[最小生成树之Prim算法]-C++ 定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.最小生成树可以用kr ...

  9. 【转载】最小生成树之Kruskal算法

    给定一个无向图,如果它任意两个顶点都联通并且是一棵树,那么我们就称之为生成树(Spanning Tree).如果是带权值的无向图,那么权值之和最小的生成树,我们就称之为最小生成树(MST, Minim ...

随机推荐

  1. docker/qemu中是如何对设备管理的

    文件系统中包括实际的磁盘中可读可写的. 容器中看到的设备是啥子呢?--docker qemu也是一样,在qemu中添加一个设备的物理意义是啥子嘛 其实设备也没啥好新奇的,不就是一个普通的文件么,然后在 ...

  2. Redis使用手册

    简介 Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型. Key-Value数据库. Redis面向互联网的方案提供了三种形式: 1.主从 主机进行写操作, ...

  3. BZOJ4321 queue2(动态规划)

    考虑套路地将1~n依次加入排列.设f[i][j]为已将1~i加入排列,有j对不合法的方案数.加入i+1时可能减少一对不合法的,可能不变,可能增加一对,对于i+1与i的关系再增设0/1/2状态表示i与左 ...

  4. hdu 1598 find the most comfortable road (并查集)

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  5. Link Cat Tree (连喵树) 学习笔记

    Link Cat Tree 一.感性定义 所谓连喵树,即一种对森林支持修改,查询,连边,删边等操作的数据结构(姑且算她是吧).她用一颗颗互相连接的辅助树维护原森林的信息,辅助树相互连接的边叫虚边,辅助 ...

  6. 微信小程序,设置所有标签样式

    page, view, scroll-view, swiper, movable-area, cover-view, text, icon, rich-text, progress, button, ...

  7. taotao订单系统

    taotao订单系统需求分析.注意点.代码 需要注意的地方: 1.下订单功能一定要使用关系型数据库,因为其设计到钱,而noSql数据库相比来说丢失数据的风险更大. 但是查看订单列表.查看订单详情等功能 ...

  8. Codeforces 937.C Save Energy!

    C. Save Energy! time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  9. JavaScript学习笔记——浅拷贝、深拷贝

    参考自:http://www.cnblogs.com/yichengbo/archive/2014/07/10/3835882.html 一.数组的深浅拷贝 在使用JavaScript对数组进行操作的 ...

  10. vue2.0基础知识,及webpack中vue的使用

    ## 基础指令 ## [v-cloak]{         Display:none;     }     <p v-cloak>xx{{msg}}xx</p> //解决闪烁问 ...