Kruskal算法来构造最小生成树,我总结了分为以下步骤:

(1)建图,构造Kruskal边集,边集元素应该包括该边的起始顶点、终止顶点、权值;

(2)将边集按权值从小到大的顺序进行排序;

(3)从小到大依次从Kruskal边集中取边加入最小生成树集合,判断条件:将该边加入最小生成树集合,与生成树集合中原有的边不构成环;

(4)最小生成树集合中元素(构成生成树的边)的个数为原图顶点数-1时,代表最小生成树构造完毕。

Kruskal核心伪代码如下:

Kruskal(MGragh *Gra)
{
对Kruskal边集按权值从小到大排序 for (边集)
{
// 判断边集中的边能否加入最小生成树集合 n=该边的起始顶点所能到达的最新顶点
m=该边的终止顶点所能到达的最新顶点 如果n等于m 说明该边能够成环路,所以不能加入最小生成树集合 如果n不等于m 说明该边可以加入最小生成树集合
{
更新:n能够到达m
}
}
}

实例:

源代码:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_VERTEX_NUM 100
#define MAX_EDGE_NUM 200
#define MAX_VERTEX_NAMELEN 100 typedef struct{
char name[MAX_VERTEX_NAMELEN];
}VerType; // 图的邻接矩阵存储结构
typedef struct{
int VertexNum,EdgeNum; // 顶点数,边数
VerType Vertex[MAX_VERTEX_NUM]; // 顶点集
int Edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 边集
}MGragh; // 克鲁斯卡尔边集
typedef struct{
int b; // 起始顶点
int e; // 终结顶点
int w; // 权值
}KruskalEdge;
KruskalEdge edge[MAX_EDGE_NUM]; // 快速排序cmp
int cmp(const void *a, const void *b)
{
KruskalEdge *c = (KruskalEdge *)a;
KruskalEdge *d = (KruskalEdge *)b; // 权值从小到大排序 权值相同则按起始顶点从小到大排序
if (c->w != d->w){
return c->w - d->w;
}
else{
return c->b - d->b;
}
} // 邻接矩阵建图及建立克鲁斯卡尔边集
void CreateMGragh(MGragh *Gra)
{
int i,j,k,w;
char v1[MAX_VERTEX_NAMELEN],v2[MAX_VERTEX_NAMELEN]; printf("请输入顶点数及边数(顶点数 边数)\n");
scanf("%d %d%*c",&(Gra->VertexNum),&(Gra->EdgeNum)); printf("请输入顶点信息\n");
for (i=; i<Gra->VertexNum; i++){
printf("%d.",i+);
gets(Gra->Vertex[i].name);
} // 初始化邻接矩阵
for (i=; i<Gra->VertexNum; i++){
for (j=; j<Gra->VertexNum; j++){
Gra->Edge[i][j] = ;
}
}
printf("请输入边信息(顶点,顶点,权值)\n");
for (i=; i<Gra->EdgeNum; i++){
printf("%d.",i+);
scanf("%[^,]%*c%[^,]%*c%d%*c",v1,v2,&w); for (j=; j<Gra->VertexNum; j++){
for (k=; k<Gra->VertexNum; k++){
if (strcmp(Gra->Vertex[j].name,v1) == && strcmp(Gra->Vertex[k].name,v2) == ){
Gra->Edge[j][k] = Gra->Edge[k][j] = w; // 构造克鲁斯卡尔边集 使起始顶点<终止顶点
if (j<k){
edge[i].b = j;
edge[i].e = k;
edge[i].w = w;
}
else{
edge[i].b = k;
edge[i].e = j;
edge[i].w = w;
}
}
}
}
} // 将克鲁斯卡尔边集按权值从小到大排序
qsort(edge,Gra->EdgeNum,sizeof(edge[]),cmp);
} // 找到顶点t所能到达的在时间顺序上最新的点
// 例如p[0]=6 代表第0个点能够到达第6个点
int FindLastArrived(int *p, int t)
{
while (p[t] > ){
t = p[t];
}
return t;
} // 克鲁斯卡尔算法构造最小生成树
void MiniTreeByKruskal(MGragh *Gra)
{
int i,n,m;
int p[MAX_VERTEX_NUM]; // 初始化辅助数组
for (i=; i<Gra->VertexNum; i++){
p[i] = ;
} printf("\nKruskal算法构造最小生成树为:\n");
for (i=; i<Gra->EdgeNum; i++){
n = FindLastArrived(p,edge[i].b);
m = FindLastArrived(p,edge[i].e);
if (n != m){ // 如果n==m 说明存在环路
p[n] = m; // 将边加入生成树,并令n能到达m
printf("(%s --> %s) %d\n",Gra->Vertex[edge[i].b].name,Gra->Vertex[edge[i].e].name,edge[i].w);
}
}
} int main()
{
MGragh g;
CreateMGragh(&g);
MiniTreeByKruskal(&g);
return ;
}

测试用例及结果:

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

  1. c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树

    c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...

  2. c/c++ 用普利姆(prim)算法构造最小生成树

    c/c++ 用普利姆(prim)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: ​ 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路.这时 ...

  3. 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)

    主要参考资料:数据结构(C语言版)严蔚敏   ,http://blog.chinaunix.net/uid-25324849-id-2182922.html   代码测试通过. package 图的建 ...

  4. 利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

    题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个 ...

  5. kruskal算法求最小生成树(jungle roads的kruskal解法)

    注意: 注意数组越界问题(提交出现runtimeError代表数组越界) 刚开始提交的时候,边集中边的数目和点集中点的数目用的同一个宏定义,但是宏定义是按照点的最大数定义的,所以提交的时候出现了数组越 ...

  6. 克鲁斯卡尔(Kruskal)算法求最小生成树

    /* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...

  7. Prim算法、Kruskal算法和最小生成树 | Minimum Spanning Tree

    graph to tree非常有趣! 距离的度量会极大地影响后续的分析,欧式距离会放大差异,相关性会缩小差异,导致某些细胞群分不开. 先直观看一下,第一个是Prim,第二个是Kruskal.但是肯定都 ...

  8. Kruskal算法:最小生成树

    //Kruskal算法按照边的权值从小到大查看一遍,如果不产生圈(重边等也算在内),就把当前这条表加入到生成树中. //如果判断是否产生圈.假设现在要把连接顶点u和顶点v的边e加入生成树中.如果加入之 ...

  9. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

随机推荐

  1. [转载]如何重装Grub,使其可以引导双系统

    引言: GRUB是一个多重操作系统的启动管理器.用来引导不同的系统,如windows,Linux.一般来说要先装Windows,后装Linux,这样grub才能生效(grub存在于linux的安装中) ...

  2. 解决windows下eclipse中android项目关联android library project

    关于 在项目中导入 关联 library project 的问题,有时候会出现如下状况 在windows系统下,library project必须和project处于相同的盘符中 如果在不同盘符,pr ...

  3. C++ 11 笔记 (一) : lambda

    时至今日都是我咎由自取,错就是错,与任何人无关.掉进C++98的各种坑里无法自拔的抖M感,让我选择了华丽丽的无视C++11,导致今日面对开源的代码到各种看不懂的地步,一入C++深似海,我今天愿意承担一 ...

  4. POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

    题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...

  5. JavaScript模块化开发实例

    最近接触了一些JavaScript开发的例子,在这里与大家一起分享一下: 例子:当我们一个团队在写Js文件的时候,你一个人写的JS代码自己可以看懂也可以维护,但是别人想对你的JS进行扩展的话,如果都在 ...

  6. IT专业人士如何更有效的学习专业知识

    查看: http://www.cnblogs.com/suizhouqiwei/archive/2010/05/17/1737265.html 书:http://www.cnblogs.com/wxi ...

  7. 怎么样删除eclipse已经记录svn的地址

    eclipse-->window-->show view-->svn选项卡中选中要删除的svn链接,点击右键废弃即可. 1.

  8. C++控制台程序中使用定时器

    转自博客:http://www.cnblogs.com/phinecos/archive/2008/03/08/1096691.html 作者:洞庭散人 “我现在项目是一个控制台程序,用到的Win32 ...

  9. Android ViewDragHelper源码解析

    在自定义ViewGroup的过程中,如果涉及到View的拖动滑动,ViewDragHelper的使用应该是少不了的,它提供了一系列用于用户拖动子View的辅助方法和相关的状态记录,像Navigatio ...

  10. Android 颜色Color

    Android中使用4个数字来表示颜色,分别是alpha.红(red).绿(green).蓝(blue)四个颜色值(ARGB).每个数字取值0-255,因此一个颜色可以用一个整数来表示.为了运行效率, ...