库鲁斯卡尔(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. Java中输入输出流

    InputStream:所有字节输入流的所有类的超类. read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲数组b中 reset()将此流重新定位到最后一次对此流调用mark方法 ...

  2. [剑指Offer] 7.斐波那契数列

    class Solution { public: int Fibonacci(int n) { ] = {}; res[] = ; res[] = ; ;i < n;i ++){ res[i] ...

  3. NOIP2018复赛 游记

    Day -? 停了两个星期的课,逃了一场期中考试.随便做了点题并不知道有什么用.见不到夫人很难受. Day 0 依然没有跟学校走.据说今年合肥居然不下雨,印象里每年这个时候来到这里都是阴雨连绵……突然 ...

  4. javascript prototype原型链的原理

    javascript prototype原型链的原理 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/javasc ...

  5. BZOJ3529 [Sdoi2014]数表 【莫比乌斯反演】

    3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2151 Solved: 1080 [Submit][Status ...

  6. CodeForces 167B - Wizards and Huge Prize 期望概率dp

    初步分析:把赢了的巡回赛的a值加起来就是最后的剩余空间 这个明显的是状态转移的dp啊,然而他的状态比较骚是个数组,表示剩余空间,f(i,j,b),i表示比到第几场,j表示赢了几场,b就是里面的核心状态 ...

  7. 适用于iview的表格转Excel插件

    在网上找的一个表格转excel插件,经过修改后使其适用于iview中的table组件 let idTmr; const getExplorer = () => { let explorer = ...

  8. at用法小记

    By francis_hao    Aug 22,2017   at – 设置稍后执行的作业. 概要 at [-V] [-f file] [-mMlv] timespec...at [-V] [-f ...

  9. [hdu 2102]bfs+注意INF

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的……把INF改成I ...

  10. MongoDB加索引

    1.登陆MongoDB, 命令行在MongoDB主目录下执行:mongo -port 27017 2.切换至需要添加索引的db 并授权 use MeetingBooking db.auth({&quo ...