专栏简介 :java语法及数据结构

题目来源:leetcode,牛客,剑指offer.

创作目标:记录学习MySql学习历程

希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长.

学历代表过去,能力代表现在,学习能力代表未来!


目录

1. 最小生成树

1.1 Kruskal(克鲁斯卡尔) 算法

1.2 Prime(普里姆) 算法


1. 最小生成树

连通图中的每一棵生成树 , 都是原图的极大无环子图 , 即: 从中删去任何一条边 , 生成树就不再连通;反之 , 在其中引入任何一条新边 , 都会形成一条回路.

若连通图由n个顶点组成 , 则其生成树必含n个顶点和n-1条边 , 因此构造最小生成树有三个准则:

  • 1.只能使用图中的边来构造最小生成树
  • 2.只能使用恰好n-1条边来连接图中的n个顶点
  • 3.选用的n-1条边不能构成回路 

常见求解最小生成树的算法有: Kruskal算法和Prime算法.两种算法都采用逐步求解的贪心策略.

贪心算法: 通过局部最优解来推出全局最优解.


1.1 Kruskal(克鲁斯卡尔) 算法

给定一个有n个顶点的连通网络N={V,E}

首先构造一个由这n个顶点组成 , 不含任何边的图G={V,NULL}.

其次不断从E中取出权值最小的一条边(若有多条任选其一) , 若该边的两个顶点来自不同的连通分量 , 则将此边加入到G中.

如此反复 , 直到G中边数达到顶点数-1为止.

核心: 每次迭代时 , 选出权值最小且两端点不在同一连通分量上的边 , 加入生成树.

步骤分析:

  • 1.由于该算法的思想是全局贪心 , 因此将所有图中所有边全部放入优先级队列中.
  • 2.构造一个最小生成树 , 将优先级队列中的边依次加入.
  • 3.为了防止出现环 , 使用并查集判断每次取出的边的顶点是否来自同一个集合 .
  • 4.如果不是同一集合 , 将该边加入最小生成树并用并查集将该边的领接顶点放入同一个       集合.

代码示例: 

 /*** 克鲁斯卡尔算法实现* @param minTree* @return*//*** 模拟实现一条边*/static class Edge{public int srcIndex;public int destIndex;public int weight;public Edge(int srcIndex, int destIndex, int weight) {this.srcIndex = srcIndex;this.destIndex = destIndex;this.weight = weight;}}public int kruskal(GraphOfMatrix minTree) {//1.定义一个优先级队列PriorityQueue<Edge> minQ = new PriorityQueue<Edge>(new Comparator<Edge>() {@Overridepublic int compare(Edge o1, Edge o2) {return o1.weight - o2.weight;}});int n = arrayV.length;//2.遍历领接矩阵,将所有的边都放入优先级队列中for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i < j && Matrix[i][j] != Integer.MIN_VALUE) {minQ.offer(new Edge(i, j, Matrix[i][j]));}}}//3.构造并查集将符合要求的边加入到最小生成树中UnionFindSet ufs = new UnionFindSet(n);int size = 0;//记录最小生成树中边的数量int totalWeight = 0;//记录权值while (size < n - 1 && !minQ.isEmpty()) {Edge edge = minQ.poll();int srcIndex = edge.srcIndex;int destIndex = edge.destIndex;//同一边的相邻顶点不能来自同一集合if (!ufs.isSameUnionFindSet(srcIndex, destIndex)) {//将符合条件的边加入到最小生成树中minTree.addEdgeUseIndex(srcIndex, destIndex, Matrix[srcIndex][destIndex]);System.out.println("选择的边"+arrayV[srcIndex]+" -> "+arrayV[destIndex]+Matrix[srcIndex][destIndex]);size++;totalWeight += Matrix[srcIndex][destIndex];//将添加过的边的相邻顶点放入同一集合,防止出现环.ufs.union(srcIndex, destIndex);}}if (size == n - 1) {return totalWeight;} else {throw new RuntimeException("没有最小生成树");}}//按照下标将边加入到最小生成树中public void addEdgeUseIndex(int srcIndex,int destIndex,int weight){Matrix[srcIndex][destIndex] = weight;//如果是无向图邻接矩阵对称位置也要添加if (!isDirect){Matrix[destIndex][srcIndex] = weight;}}//测试克鲁斯卡尔算法public static void main(String[] args) {String str = "abcdefghi";char[] array =str.toCharArray();graph.GraphOfMatrix g = new graph.GraphOfMatrix(str.length(),false);g.initArray(array);g.addEdge('a', 'b', 4);g.addEdge('a', 'h', 8);
//g.addEdge('a', 'h', 9);g.addEdge('b', 'c', 8);g.addEdge('b', 'h', 11);g.addEdge('c', 'i', 2);g.addEdge('c', 'f', 4);g.addEdge('c', 'd', 7);g.addEdge('d', 'f', 14);g.addEdge('d', 'e', 9);g.addEdge('e', 'f', 10);g.addEdge('f', 'g', 2);g.addEdge('g', 'h', 1);g.addEdge('g', 'i', 6);g.addEdge('h', 'i', 7);graph.GraphOfMatrix kminTree = new graph.GraphOfMatrix(str.length(),false);System.out.println(g.kruskal(kminTree));kminTree.printGraph();}

构造并查集:

public class UnionFindSet {public int[] elem;public UnionFindSet(int n){this.elem = new int[n];Arrays.fill(elem,-1);}/*** 查找数据x的根节点* @param x* @return*/public int findRoot(int x){if (x < 0){throw new RuntimeException("下表不合法");}while (elem[x] >= 0){x = elem[x];}return x;}/*** 查询x1和x2是不是同一个集合* @param x1* @param x2* @return*/public boolean isSameUnionFindSet(int x1 , int x2){int index1 = findRoot(x1);int index2 = findRoot(x2);if (index1 == index2){return true;}return false;}/*** 这是合并操作* @param x1* @param x2*/public void union(int x1 , int x2){int index1 = findRoot(x1);int index2 = findRoot(x2);if (index1 == index2) return;elem[index1] = elem[index1] + elem[index2];elem[index2] = index1;}/*** 有几对关系* @return*/public int getCount(){int count = 0;for (int x:elem) {if (x < 0){count++;}}return count;}public void Print(){for (int x:elem){System.out.print(x+" ");}System.out.println();}
}

 测试结果:


1.2 Prime(普里姆) 算法

普里姆算法与克鲁斯卡尔算法类似 , 核心区别是普里姆算法采用局部贪心的思想.

首先 , 设定两个集合 , X{}已确定顶点的集合 , Y{}未确定顶点的集合.

其次 , 假设图中的顶点为 a,b,c,d,e,f,g,h,i.放入Y{}中.

然后 , 任取一个顶点放入X{}中 . 在Y{}中选择一个与该顶点相连权值最小的边 , 加入最小生成树中.

如此重复 , 直到最小生成树的边数达到顶点数-1为止.

代码示例:

/*** 普里姆算法实现* @param minTree* @param chV 图中顶点的起点* @return*/public int prime(GraphOfMatrix minTree,char chV) {int srcIndex = getIndexOfV(chV);//存储已确定的顶点Set<Integer> setX = new HashSet<>();setX.add(srcIndex);//初始化未确定的点Set<Integer> setY = new HashSet<>();int n = arrayV.length;for (int i = 0; i < n; i++) {if (i != srcIndex){setY.add(i);}}//定义一个优先级队列PriorityQueue<Edge> minQ = new PriorityQueue<>(new Comparator<Edge>() {@Overridepublic int compare(Edge o1, Edge o2) {return o1.weight - o2.weight;}});//遍历srcIndex连接出去的边,并放入优先级队列中排序for (int i = 0; i < n; i++) {if (Matrix[srcIndex][i] != Integer.MIN_VALUE){minQ.offer(new Edge(srcIndex,i,Matrix[srcIndex][i]));}}int size = 0;int totalWeight = 0;while (!minQ.isEmpty()){Edge min = minQ.poll();int srcI = min.srcIndex;int destI = min.destIndex;if (setX.contains(destI)){//此时会构成环}else {minTree.addEdgeUseIndex(srcI,destI,Matrix[srcI][destI]);System.out.println("起点"+arrayV[srcI]+" -> "+"终点"+arrayV[destI]+Matrix[srcI][destI]);size++;totalWeight+=min.weight;if (size == n-1){return totalWeight;}//更新两个集合setX.add(destI);setY.remove(destI);//把dest连出去的所有边也放到优先级队列中for (int i = 0; i < n; i++) {if (Matrix[destI][i] != Integer.MIN_VALUE && !setX.contains(i)){minQ.offer(new Edge(destI,i,Matrix[destI][i]));}}}}throw new RuntimeException("没有最小生成树");}//测试普里姆算法public static void main3(String[] args) {String str = "abcdefghi";char[] array =str.toCharArray();GraphOfMatrix g = new GraphOfMatrix(str.length(),false);g.initArray(array);g.addEdge('a', 'b', 4);g.addEdge('a', 'h', 8);
//g.addEdge('a', 'h', 9);g.addEdge('b', 'c', 8);g.addEdge('b', 'h', 11);g.addEdge('c', 'i', 2);g.addEdge('c', 'f', 4);g.addEdge('c', 'd', 7);g.addEdge('d', 'f', 14);g.addEdge('d', 'e', 9);g.addEdge('e', 'f', 10);g.addEdge('f', 'g', 2);g.addEdge('g', 'h', 1);g.addEdge('g', 'i', 6);g.addEdge('h', 'i', 7);GraphOfMatrix primTree = new GraphOfMatrix(str.length(),false);System.out.println(g.prime(primTree,'a'));primTree.printGraph();}

[Java]图论进阶--最小生成树算法相关推荐

  1. 如何在 Java 中实现最小生成树算法

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...

  2. 证明kruskal算法求解图的最小生成树具有贪心选择性质_将并查集应用在图论中的最小生成树算法——Kruskal...

    点击上方蓝字,和我一起学技术. 今天是算法和数据结构专题的第19篇文章,我们一起来看看最小生成树. 我们先不讲算法的原理,也不讲一些七七八八的概念,因为对于初学者来说,看到这些术语和概念往往会很头疼. ...

  3. 数据结构与算法邹永林PDF_真香系列:耗时大半个月收整全套「Java架构进阶pdf」没白费,终于可以安心备战2021了!...

    2021就这么来了,马上就要开启备战今年的"金三银四"了.辛亏在2020的最后半月花了我大半个月时间收整了全套的「Java架构进阶pdf」,这一波下来,刷完你就会知道,真真香啊,我 ...

  4. 学习SpringBoot:知乎超赞回答:Java如何进阶?分享面经

    前言 Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 是 Spring 家族中的一个安全管理框架,提供了一套 Web 应用安全性的完整解决方案.在用户认证 ...

  5. 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。

    十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...

  6. Java培训进阶书籍推荐,赶快收藏起来!

    最近有很多学习或者已经在工作的java技术的同学都想要更进一步的提升自己,那么阅读书籍可以给大家带来帮助,今天,小编将分享过去几年中一些最好的Java培训进阶书籍,您可以在2021年阅读这些书籍,以更 ...

  7. Java工程师进阶知识完全扫盲, 太全了!!

    项目简介 本期介绍的开源项目名称叫做:advanced-java 中文名:互联网 Java 工程师进阶知识完全扫盲,该项目主要是为Java开发工程师提供进阶知识讲解,从而提升Java工程师技术与能力! ...

  8. 两万字长文总结,梳理 Java 入门进阶那些事

    两万字长文总结,梳理 Java 入门进阶那些事 先给大家看下完整的思维导图,也是这篇文章的主要脉络. Java从入门到进阶学习路线 主导三个项目,让我独当一面 能力提升你要怎么学 全篇总结 Java ...

  9. 两万字长文总结,梳理 Java 入门进阶哪些事(推荐收藏)

    两万字长文总结,梳理 Java 入门进阶哪些事(推荐收藏) 程序员小跃 2021-01-12 13:19:09  23  收藏 分类专栏: Java学习之路 文章标签: java 数据库 redis ...

最新文章

  1. D3D中简单的截图方法 (转)
  2. IBM中国研究院被曝已全面关闭
  3. HBase表结构设计(结构、创建、压缩、分区、命名空间等)
  4. Python 个人的失误记录之str.replace
  5. FCN 学习: Semantic Segmentation
  6. 第二课 决策树与随机森林
  7. WinForm 处理未处理的异常 Application.ThreadException + AppDomain.CurrentDomain.UnhandledException
  8. oracle,sqlserver,mysql区别
  9. django web app_妹子用半天时间开发一个员工管理系统,没错django就是这么强悍
  10. Python 学习入门(22)—— 线程同步
  11. 正在搜索需要的文件_搜索电脑文件,只需要0.01s
  12. 2022 年“泰迪杯”数据分析技能赛——竞赛作品的自动评判(Python代码实现)
  13. 破解校园网“一人一号” 高校学子必备秘籍
  14. PHP经典面试题——数据库优化
  15. 利用开放的isbn查询Api接口录入图书信息,工作效率倍增
  16. 什么是目标检测?理论+实操(github全面解析)?(持续更新中)
  17. 2.天猫商品数据爬虫(已模拟登录)
  18. Android 文件中断续传
  19. 聚类(2)——层次聚类 Hierarchical Clustering
  20. 数据分析的基本思想是什么

热门文章

  1. AutoCAD自定义线型的线性比例设计方法
  2. service引入其他dao报错_绝了!这款工具让SpringBoot不再需要Controller、DAO、Mapper!...
  3. R关于一些字符串报错
  4. 2020-12-03 Matlab --CUDNN_STATUS_EXECUTION_FAILED
  5. css会对网站排名有影响吗,网站是如何推广的?DIVCSS网页相似太多影响排名?
  6. 解决Xshell运行程序中途断网问题
  7. Reusing Discriminators for Encoding: Towards Unsupervised Image-to-Image Translation(CVPR20)
  8. day21:shell
  9. centos7安装mysql8.0.31版本
  10. 最新站长必备在线工具箱系统源码/含上百款工具/带后台版本/自适应模板/优化修复版