Kruskal算法是最小生产树算法
算法的步奏:
初始情况下:
把所有的节点看成是独立的一颗森林。
算法的核心就是尽可能找出权值最小的边把这些分散的森林组合成一个完整的包含所有顶点的森林。
使用的是贪心算法,贪心的证明可以参看算法导论。
使用一个以边的权值为基准的优先级队列来维护所有的边 edges
for(Edge edge:edges){
node src = deg.src;
node des = des.des;
// 判断src 和des 是否在同一个森林
如果不在同一个森林,则找到一条贪心边,
把src 对应的森林 和 des对应的森林 合并成一个森林
}
上述算法需要 判断两个节点是否属于同一个森林,也需要对森林进行合并,。
这用到了数据结构中 集合操作的知识, 即判断一个点属于哪个集合,合并两个集合
本文使用的是 set来存储集合节点, set中所有node 的id和作为集合标识。
unio的时间复杂度为 o( v),所以 对于 E 个操作,上述的复杂度为 o(EV)
更优秀的数据结构为 采用压缩路径的并查集结构。 E 个操作的时间复杂度能到 aE.
参考算法导论高级数据结构,不相交的数据集。
所以kruskal算法时间复杂度是可以为 ElogV的。 主要在于排序。 完整的代码如下:
import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; /** * Kruskal spanning tree * @author slj * */ public class Kruskal { TreeSet<Edge> edges = new TreeSet<Edge>(); Set<Edge> spaningTree = new TreeSet<Edge>(); Map<String,Node> nodes= new HashMap<String,Node>(); public void addNode(String[] ids){ for(int i=0;i<ids.length;i++){ nodes.put(ids[i],new Node(ids[i])); } } public void addEdge(String src,String des,int weight){ Node srcN = nodes.get(src); Node desN = nodes.get(des); Edge edge = new Edge(srcN,desN,weight); edges.add(edge); } public void SpTree(){ for(Edge edge:edges){ Node src = edge.src; Node des = edge.des; // 判断src 和des 是否在一个森林中 String src_id = src.getMySetIndentifer(); String des_id = des.getMySetIndentifer(); if(src_id.equals(des_id)){ continue; }else{ // unino (src_forest,des_forest) Set<Node> src_forest = src.getMysets(); Set<Node> des_forest = des.getMysets(); Set<Node> union = new HashSet<Node>(); StringBuilder unionId = new StringBuilder(); for(Node node:src_forest){ unionId.append(node.id); union.add(node); } for(Node node:des_forest){ unionId.append(node.id); union.add(node); } //set the new relationship for(Node node:union){ node.setMysets(union); node.setMySetIndentifer(unionId.toString()); } spaningTree.add(edge); } } } public static void main(String[] args) { Kruskal ins = new Kruskal(); ins.addNode(new String[]{ "a","b","c", "d","e","f", "g","i","h"}); ins.addEdge("a", "b", 4); ins.addEdge("a", "h", 8); ins.addEdge("b", "h", 11); ins.addEdge("b", "c", 8); ins.addEdge("c", "d", 7); ins.addEdge("c", "f", 4); ins.addEdge("c", "i", 2); ins.addEdge("d", "f", 14); ins.addEdge("d", "e", 9); ins.addEdge("e", "f", 10); ins.addEdge("f", "g", 2); ins.addEdge("g", "i", 6); ins.addEdge("g", "h", 1); ins.addEdge("i", "h", 7); ins.SpTree(); for(Edge edge:ins.spaningTree){ System.out.println(edge); } } } class Node { String id =""; /** * 每个节点所在的集合 */ String mySetIndentifer ; Set<Node> mysets = new HashSet<Node>(); public Node(String id ){ this.id = id; mySetIndentifer = id; mysets.add(this); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getMySetIndentifer() { return mySetIndentifer; } public void setMySetIndentifer(String mySetIndentifer) { this.mySetIndentifer = mySetIndentifer; } public Set<Node> getMysets() { return mysets; } public void setMysets(Set<Node> mysets) { this.mysets = mysets; } } class Edge implements Comparable<Edge>{ Node src = null; Node des = null; int weight = 0; public Edge(Node srcN, Node desN, int weight) { this.src = srcN; this.des = desN; this.weight = weight; } @Override public int compareTo(Edge o) { if(this.weight >= o.weight){return 1;} else{return -1;} } @Override public String toString() { // TODO Auto-generated method stub return src.id+"<-->"+des.id +" weight: "+weight; } }
相关推荐
Kruskal算法是一种用于寻找图的最小生成树的经典算法,由Joseph Kruskal在1956年提出。它的核心思想是贪心策略,即在每次选择边时,优先选择权重最小的边,同时避免形成环路。在这个过程中,我们可以使用并查集...
代码 最小生成树kruskal算法离散型优化问题代码代码 最小生成树kruskal算法离散型优化问题代码代码 最小生成树kruskal算法离散型优化问题代码代码 最小生成树kruskal算法离散型优化问题代码代码 最小生成树kruskal...
在这个问题中,Prim算法和Kruskal算法是两种常用的方法。 1. Prim算法: Prim算法是一种贪心策略,它从一个起始顶点开始,逐步添加边,每次添加一条与已选择顶点集形成最小权重边的新边。这个过程不断进行,直到...
### 使用Prim和Kruskal算法构建最小生成树 在图论中,最小生成树(Minimum Spanning Tree, MST)是一个非常重要的概念。对于一个连通的无向图来说,如果存在一个子图,它包含原图的所有顶点,并且这些顶点通过边...
Kruskal算法python实现,包括无向图的绘制,需要自己在桌面上先建关于无向图的TXT
本文将详细介绍两种经典算法来解决最小生成树问题:Prim算法和Kruskal算法,并以C语言实现为例进行讲解。 ### Prim算法 Prim算法是一种贪心算法,其基本思想是从一个初始节点开始,逐步添加最短的边,直到连接到...
数据结构课程设计报告最小生成树Kruskal算法 数据结构课程设计报告中,我们将使用Kruskal算法来生成最小生成树,该算法是图论中的一种经典算法,能够在给定的图中找到最小生成树。下面,我们将对Kruskal算法的实现...
最小生成树Kruskal算法 标题:最小生成树Kruskal算法 描述:java编写的最小生成树Kruskal算法,参考:算法设计和分析 标签:最小生成树 Kruskal算法 JAVA 知识点概述: 1. 最小生成树(Minimum Spanning Tree)...
Matlab版Prim Kruskal算法实现文档 一、Prim算法 Prim算法是图论中的一种常用算法,用于求解最小生成树问题。其基本思想是以局部最优化谋求全局的最优化。该算法的实现步骤如下: 1. 设G=(V,E)是一个无向连通网...
### 数学建模中的Kruskal算法:构建最小生成树 #### 一、Kruskal算法简介 Kruskal算法是解决最小生成树问题的一种高效算法,在数学建模与计算机科学领域有着广泛的应用。该算法由Joseph Kruskal在1956年提出,其...
Prim算法和Kruskal算法的Matlab实现 Prim算法和Kruskal算法是两种常用的最小生成树算法,它们在计算机仿真和软件开发中有广泛的应用。本文将对这两种算法进行深入的分析和比较,并使用Matlab实现它们的代码实现。 ...
数据结构课程设计中的Kruskal算法是图论领域的一个重要概念,主要应用于寻找图的最小生成树。在本课程设计中,我们利用MFSET(即Disjoint Set,也称为并查集)的数据结构来实现这一算法。MFSET是一种高效处理集合...
### 最小生成树Kruskal算法详解 #### 算法背景与定义 最小生成树(Minimum Spanning Tree,简称MST)是图论中的一个经典问题,涉及到在一个加权图中寻找一棵包含所有顶点的子图,使得这棵子图的总权重最小。在实际...
Kruskal算法是一种经典的图论算法,用于寻找加权无向图中的最小生成树。最小生成树是指在不增加边的权重的情况下,连接所有顶点的树形子图。Kruskal算法的主要思想是按边的权重递增顺序选择边,并在选择过程中避免...
Kruskal算法同样是一种贪心策略,它按照边的权重从小到大排序,依次选择边,但避免形成环路。具体步骤如下: 1. **边的排序**:将图中的所有边按照权重进行升序排序。 2. **并查集初始化**:建立一个表示顶点关系的...
Prim算法和Kruskal算法是两种常用的求解最小生成树的方法,它们各有特点和适用场景。 1. **Prim算法**: Prim算法是从一个顶点开始,逐步添加边来构建最小生成树。它每次选择与当前树连接且权重最小的边,直到所有...