原文:算法起步之Kruskal算法

说完并查集我们接着再来看这个算法,趁热打铁嘛。什么是最小生成树呢,很形象的一个形容就是铺自来水管道,一个村庄有很多的农舍,其实这个村庄我们可以看成一个图,而农舍就是图上的每个节点,节点之间有很多的路径,而铺自来水管道目的就是为了让每家都能用上自来水,而至于自来水怎么铺就不关心了,而铺管子的人就会想如何才能最生材料,那么最省材料的一条路径就是我们这个图的最小生成树。而如何去构建一个最小生成树呢?这个就用到了我们之前说的贪心策略。这里的觉得点就是一直寻找安全边,所以构建最小生成树的过程可以描述成,循环一直寻找安全边加入到树中,直到树中包含所有节点,什么是安全边?安全边的定义就是假设集合A是我们的最小生成树的子集,每一步都是选择一条边是的A还是最小生成树的子集则那条边就是安全边。

根据安全边选择策略不同有两种最短路径算法,分别是Kruskal算法跟prim算法。我们先来说Kruskal算法。首先我们先看一下图,我觉得图比说要好理解的多。

大家可能已经看出来了,kruskal算法寻找安全边的方式,就是在所有的边中找最小的表,只要两个节点是两个不相交集合,就加入到最小生成树中,直到所有的节点都连接起来。我用汉字写一下伪代码:

1循环所有的边;2构建一个最小优先队列;3构建一个并查集;4直到构建成最小生成树{  从优先队列取出一个值,判断两个节点是不是不相交集合,是否加入到最小树中。  }结束

下面我们就安装伪代码来写。可能相比之前的代码要多一点,但是基本思想都一样,代码多是因为要写一个javabean跟实现一个并查集,并查集我们在上一篇已经讲过http://blog.csdn.net/idlear/article/details/19556587,最小优先队列也已经说过http://blog.csdn.net/idlear/article/details/18997685大家可以参考之前的文章。

这个是边的javabean不需要解释了吧。

class Bian implements Comparable<Bian>{
private int left;
private int right;
private int value;
public Bian(int i, int j, int k) {
this.left=i;
this.right=j;
this.value=k;
}
public int getLeft() {
return left;
}
public void setLeft(int left) {
this.left = left;
}
public int getRight() {
return right;
}
public void setRight(int right) {
this.right = right;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public int compareTo(Bian o) {
if (this.getValue()>o.getValue()) {
return -1;
}
return 1;
}
}

并查集。

class Ufs{
private int[] father;
private int[] rank; public void makeset(int max) {
father = new int[max];
rank = new int[max];
for (int i = 0; i < father.length; i++) {
father[i] = i;
}
} public void union(int x, int y) {
if (rank[x] > rank[y]) {
father[y] = x;
} else {
if (rank[x] == rank[y]) {
rank[y]++;
}
father[x] = y;
}
} public int findset(int x) {
if (father[x] != x) {
father[x] = findset(father[x]);
}
return father[x];
}
}

核心代码其实就是一个循环过程,而之前的代码也全是在先前的准备工作。这里如果有几个类没有见过都是java中的工具类,这些类的作用可以查一下api文档。

public void kruskal(int[][] map) {

		Ufs ufs=new Ufs();
ufs.makeset(map.length);
ArrayList list=new ArrayList();
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map.length; j++) {
if(map[i][j]!=0){
Bian b=new Bian(i,j,map[i][j]);
list.add(b);
}
}
}
int max=0;
while(max<=map.length-1){
Collections.sort(list);
Bian b=(Bian) list.remove(1);
int x=b.getLeft();
int y=b.getRight();
if(ufs.findset(x)!=ufs.findset(y)){
ufs.union(x, y);
System.out.println("连接"+x+","+y+"路径长度为"+b.getValue());
max++;
}
}
}

友情提示:转载请注明出处【作者idlear    博客http://blog.csdn.net/idlear/article/details/19301373】

算法起步之Kruskal算法的更多相关文章

  1. 算法起步之Prim算法

    原文:算法起步之Prim算法 prim算法是另一种最小生成树算法.他的安全边选择策略跟kruskal略微不同,这点我们可以通过一张图先来了解一下. prim算法的安全边是从与当前生成树相连接的边中选择 ...

  2. 算法起步之Bellman-Ford算法

    原文:算法起步之Bellman-Ford算法 从这篇开始我们开始介绍单源最短路径算法,他是图算法之一,我们前面说的贪心,图的遍历,动态规划都是他的基础,单源最短路径其实说的就是图中节点到节点的最短路径 ...

  3. 算法起步之Dijkstra算法

    原文:算法起步之Dijkstra算法 友情提示:转载请注明出处[作者 idlear    博客:http://blog.csdn.net/idlear/article/details/19687579 ...

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

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

  5. 算法8-4:Kruskal算法

    Kruskal算法用于计算一个图的最小生成树.这个算法的过程例如以下: 依照边的权重从小到达进行排序 依次将每条边添加到最小生成树中,除非这条边会造成回路 实现思路 第一个步骤须要对边进行排序,排序方 ...

  6. 算法笔记_066:Kruskal算法详解(Java)

    目录 1 问题描述 2 解决方案 2.1 构造最小生成树示例 2.2 伪码及时间效率分析 2.3 具体编码(最佳时间效率)   1 问题描述 何为Kruskal算法? 该算法功能:求取加权连通图的最小 ...

  7. 算法实践--最小生成树(Kruskal算法)

    什么是最小生成树(Minimum Spanning Tree) 每两个端点之间的边都有一个权重值,最小生成树是这些边的一个子集.这些边可以将所有端点连到一起,且总的权重最小 下图所示的例子,最小生成树 ...

  8. [数据结构]最小生成树算法Prim和Kruskal算法

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树.  例如,对于如上图G4所示的连通网可以有多棵权值总 ...

  9. 无向带权图的最小生成树算法——Prim及Kruskal算法思路

    边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...

随机推荐

  1. DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)

    函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...

  2. git项目同时支持多个远端仓库

    git项目同时支持多个远端仓库 为了防止github被墙,最好在国内的托管商做一个备份,这就需要同时提交到多个远端仓库,例如一个open source项目同时要提交csdn和github,url分别是 ...

  3. C语言指针和数组知识总结(下)

    一.数组指针: 数组指针就是一个指针,只不过它指向的是一个数组.可以通过如下方式来定义 typedef int Array[5]; //数组类型 Array* m;      //数组定义 还有一种更 ...

  4. 使用Eclipse EE开发web项目

    最近使用EclipseEE开发web项目,遇到了以下几个问题: 1. 通过tomcat启动web应用的时候,总是提示找不到包或者class. 经过排查,发现所有的jar包并没有放到WEB-INF/li ...

  5. 基于visual Studio2013解决面试题之0510连续数之和

     题目

  6. Swift - 使用Core Data进行数据持久化存储

    一,Core Data介绍 1,Core Data是iOS5之后才出现的一个数据持久化存储框架,它提供了对象-关系映射(ORM)的功能,即能够将对象转化成数据,也能够将保存在数据库中的数据还原成对象. ...

  7. 管理支撑办公系统技术架构选型对照讨论(J2EE与SOA对照)

    续:管理支撑办公系统技术架构选型及相关技术应用范围.方法分析 M域办公系统改造.整合涉及到OA.业务流程.部室信息站点.部室专业管理等系统和信息共享等新需求,从信息化视角来看,内容多并且杂,这里核心业 ...

  8. Mongdb 访问

    http://114.55.75.xx/pics/201607040751367d21a38035bd4da7abd4473783f85f7a

  9. wp实例开发精品文章源码推荐

    WP8 启动媒体应用         这个示例演示了如何选择正确的msAudioCategory类别的音像(AV)流来配置它作为一个音频播放流.具体地说,这个示例执行以下操作:启动一个媒体应用与“媒体 ...

  10. zoj 1107 FatMouse and Cheese(记忆化搜索)

    题目链接:点击链接 题目大意:老鼠从(0,0)出发,每次在同一个方向上最多前进k步,且每次到达的位置上的数字都要比上一个位置上的数字大,求老鼠经过的位置上的数字的和的最大值 #include<s ...