一.简介

连通图:任意2节点之间都有路径相通

最小生成树:最小权重生成树
一个 n 结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边(n-1)。 最小生成树可以用prim(普里姆)算法或kruskal(克鲁斯卡尔)算法求出。

二.实现

该图的最小生成树权值和为:19

1.普里姆算法

设T为最小生成树集合,V为节点集合,U为还未放入T集合的节点集合(U=V-T)

1.先选取任意节点放入T

2.获取T 与 U 集合中最小权值节点v’,并加入T集合

3.循环2直到集合T中有n-1条边

2.克鲁斯卡尔算法

按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路(不让新选择边的2节点再次被选择)。


package com.vincent;import java.util.*;public class Main {//定义边static  class Edge{int vertex1;int vertex2;int weight;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Edge edge = (Edge) o;return vertex1 == edge.vertex1 &&vertex2 == edge.vertex2;}@Overridepublic int hashCode() {return Objects.hash(vertex1, vertex2);}@Overridepublic String toString() {return String.format("(%d,%d,%d)",vertex1,vertex2,weight);}}public static void main(String[] args) throws Exception {char[] datas = {'a','b','c','d','e','f'};int[][] graph = new int[datas.length][datas.length];graph[0][1] = 2;graph[0][2] = 3;graph[0][5] = 5;graph[1][0] = 2;graph[1][3] = 4;graph[2][0] = 3;graph[2][4] = 5;graph[3][1] = 4;graph[3][5] = 6;graph[4][2] = 5;graph[4][5] = 8;graph[5][3] = 6;graph[5][4] = 8;graph[5][0] = 5;for(int i=0;i<datas.length;i++){System.out.println(Arrays.toString(graph[i]));}System.out.println("------------------");algOfPrim(graph,datas,0);System.out.println("------------------");algOfKruskal(graph,datas);}/*** 普利姆算法* @param graph     图的邻接矩阵存储,值表示节点之间的权值* @param datas     对应节点的值* @param from      最小生成树的开始节点索引*/public static void algOfPrim(int[][] graph,char[] datas,int from){//记录节点是否访问过int[] book = new int[datas.length];//保存节点信息List<Integer> rst = new ArrayList<>();book[from] = 1;//标记为已访问rst.add(from);//n个节点的最小生成树有n-1条边for(int i=1;i<datas.length;i++){int weight = Integer.MAX_VALUE;//记录已选择索引,记录未选择索引,选择索引节点与未选择索引节点组合是当前子集中权值最小的int minSel = -1,minUnsel = -1;for(int j=0;j<rst.size();j++){for(int k=0;k<datas.length;k++){if(book[k] == 0 && graph[rst.get(j)][k] != 0 && graph[rst.get(j)][k] < weight){weight = graph[rst.get(j)][k];minSel = j;minUnsel = k;}}}rst.add(minUnsel);book[minUnsel] = 1;System.out.printf("%c->%c weight=%d\n",datas[minSel],datas[minUnsel],graph[minSel][minUnsel]);}}/*** 克鲁斯卡尔算法* @param graph* @param datas*/public static void algOfKruskal(int[][] graph,char[] datas){//图转化为Edge结构List<Edge> edges = new ArrayList<>();for(int i=0;i<graph.length;i++){for(int j=i+1;j<graph[i].length;j++){if(graph[i][j] != 0) {Edge edge = new Edge();edge.vertex1 = i;edge.vertex2 = j;edge.weight = graph[i][j];edges.add(edge);}}}Collections.sort(edges,(a,b)->{return a.weight-b.weight;});System.out.println(edges);//记录选择的节点Set<Integer> bookSet = new HashSet<>();List<Edge> rst = new ArrayList<>();for(int i=0;i<edges.size();i++){Edge edge = edges.get(i);//判断是否有回路(当前边的节点已经包含在记录集合)if(bookSet.contains(edge.vertex1) && bookSet.contains(edge.vertex2)){continue;}bookSet.add(edge.vertex1);bookSet.add(edge.vertex2);rst.add(edge);}System.out.println(rst);}
}

效果:

三.总结

普里姆算法/克鲁斯卡尔算法是解决图的最小联通的有效方法

普里姆 克鲁斯卡尔算法相关推荐

  1. 【数据结构】——图的最小生成树算法(普里姆+克鲁斯卡尔)

    这里的图指的是带权无向图,也就是无向网. 关于最小生成树 图的最小生成树要解决的问题:用最小的代价连通图中的所有顶点. 下面两种算法都是运用贪心思想,利用MST(Minimum Spanning Tr ...

  2. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  3. 最小生成树(普里姆算法【Prim】与克鲁斯卡尔算法【Kruskal】)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  4. 最小生成树——普里姆算法和克鲁斯卡尔算法

    最小生成树 用来解决工程中的代价问题. 一:普里姆算法 具体代码用C语言实现如下: typedef int VRType;typedef char InfoType;#define MAX_NAME ...

  5. 两种构造最小生成树的算法(普里姆算法,克鲁斯卡尔算法)

    (一)普里姆算法 普里姆算法求最小生成树:从生成树中只有一个顶点开始,到定点全部进入生成数为止: 2.克鲁斯卡尔算法. 思想:将所有边按其权值从小到大排一遍,从小到大依次选取边,加入最小生成树中,若加 ...

  6. 最小生成树(克鲁斯卡尔算法 普里姆算法)

    最小生成树是处理图结构中,简化图的算法:即删除一些边使得图得以简化,但应保证图中任意点都是相连通的.形成的最小生成树应该使得从顶点遍历时走过边的权值和最小.(有n个节点,则最小生成树的边数应为n-1) ...

  7. JAVA-数据结构与算法-修路问题(普里姆算法)和公交站问题(克鲁斯卡尔算法)

    修路问题(普里姆算法) 最小生成树,给定一个带权的无向连通图,如何选择一颗生成树,使树上所有边上权的总和为最小:N个顶点,N-1条边 普里姆算法,在包含n个顶点的连通图中,找出只有n-1条边,包含所有 ...

  8. 普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

    图是一种基础又重要的数据结构,图的生成树是图的一个极小连通子图.最小生成树是无向连通网的所有生成树中边的权值之和最小的一棵生成树.求图的最小生成树可以牵引出很多经典的题目,例如在N个城市之间建立通讯网 ...

  9. 最小生成树:克鲁斯卡尔算法+普里姆算法

    目录 一.最小生成树 二.克鲁斯卡尔算法 1.思路 2.示例 3.C语言代码 三.普里姆算法 1.思路 2.C语言代码 一.最小生成树 一棵最小生成树需要满足哪些条件呢? 不存在回路 对于具有n个顶点 ...

最新文章

  1. Colly源码解析——结合例子分析底层实现
  2. windows10 ubuntu 无法连接到 无法建立到 raw.githubusercontent.com 的服务器 IP 地址,解决办法
  3. C++迭代器iterator
  4. 今日头条极速版怎样签到_今日头条投放广告的费用多少钱?今日头条广告投放完整流程是怎样?...
  5. 【整数反转】算法优化笔记
  6. 16汇编 and和or实现大小写转换
  7. 牛客 - 丁姐姐喜欢Fibonacci(找规律+思维)
  8. java 高并发_Java 高并发之无锁(CAS)
  9. 前端学习(2796):实现左侧数据渲染和点击高亮
  10. java 8 中文API
  11. 周末舞会(信息学奥赛一本通-T1332)
  12. 《推荐系统笔记(五)》svd降维 —— 以图片处理为例
  13. 懒加载(延迟加载)之后,在使用数据过程中容易出现的bug
  14. 山东大学计算机学院第二校园,山东大学本科生第二校园学习经历管理办法
  15. 2019蓝桥杯国赛c++ A组
  16. 关于解决乱码问题的几个步骤
  17. 【Leetcode】1526. Minimum Number of Increments on Subarrays to Form a Target Array(配数学证明)
  18. SA6155P max9288 camera 笔记-2
  19. 【加装固态硬盘】联想小新Air15-IKBR 2018款加装固态硬盘教程
  20. 谁在用琵琶弹奏一曲东风破

热门文章

  1. 在JointJS元素中使用html
  2. IOC和AOP概念理解
  3. 怎么把mkv视频转换成mp4?
  4. 未来 我们该何去何从
  5. 成绩登记与查询系统App
  6. 怎么将较大的PDF文件进行分割
  7. 摸清企业“老底”只需要扫一扫
  8. 从单片机到嵌入式开发——(6) 定时器与串口中断
  9. Java代码规范检查插件调研及总结
  10. Java零基础到传奇的必经之路,你准备好了吗?