应用场景

思路分析

代码实现

package com.atguigu.kruskal;import java.util.Arrays;/*** @创建人 wdl* @创建时间 2021/4/6* @描述*/
public class KruskalCase {private int edgNum;//边的个数private char[] vertexs;//顶点数组private int[][] matrix;//邻接矩阵//使用INF表示两个顶点不能连通private static final int INF = Integer.MAX_VALUE;public static void main(String[] args) {char[] vertexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};//克鲁斯卡尔算法的邻接矩阵int matrix[][] = {/*A*//*B*//*C*//*D*//*E*//*F*//*G*//*A*/ {0, 12, INF, INF, INF, 16, 14},/*B*/ {12, 0, 10, INF, INF, 7, INF},/*C*/ {INF, 10, 0, 3, 5, 6, INF},/*D*/ {INF, INF, 3, 0, 4, INF, INF},/*E*/ {INF, INF, 5, 4, 0, 2, 8},/*F*/ {16, 7, 6, INF, 2, 0, 9},/*G*/ {14, INF, INF, INF, 8, 9, 0}};//大家可以在去测试其它的邻接矩阵,结果都可以得到最小生成树.//创建KruskalCase对象实例KruskalCase kruskalCase = new KruskalCase(vertexs, matrix);//输出构建的kruskalCase.print();kruskalCase.kruskal();}//构造器public KruskalCase(char[] vertexs, int[][] matrix) {//初始化顶点数和边的个数int vlen = vertexs.length;//初始化顶点,复制拷贝的方式this.vertexs = new char[vlen];for (int i = 0; i < vertexs.length; i++) {this.vertexs[i] = vertexs[i];}
//        this.vertexs=vertexs;//会修改原来的//初始化边,使用的是复制拷贝的方式this.matrix = new int[vlen][vlen];for (int i = 0; i < vlen; i++) {for (int j = 0; j < vlen; j++) {this.matrix[i][j] = matrix[i][j];}}//统计边的条数for (int i = 0; i < vlen; i++) {for (int j = i+1; j < vlen; j++) {if (this.matrix[i][j] != INF) {edgNum++;}}}}public void kruskal(){int index=0;//表示最后结果数组的索引int[] ends=new int[edgNum];//用于保存"已有最小生成树"中的每个顶点在最小生成树中的终点//创建结果数组,保存最后的最小生成树EData[] rets=new EData[edgNum];//获取图中所有的边的集合,一共有12条边EData[] edges=getEdges();System.out.println("图的边的集合"+Arrays.toString(edges)+"共"+edges.length);//按照边的权值大小进行排序(从小到大)sortEdges(edges);//遍历edges数组,将边添加到最小生成树中时,判断是否准备加入的边形成了回路,如果没有,就加入rets,否则不能加入for (int i = 0; i < edgNum; i++) {//获取到第i条边的第一个顶点int p1 = getPosition(edges[i].start);//p1=4//获取到第i条边的第2个顶点int p2 = getPosition(edges[i].end);//p2=5//获取p1这个顶点在已有的最小生成树中的终点int m=getEnd(ends,p1);//获取p2这个顶点在已有的最小生成树中的终点int n=getEnd(ends,p2);//是否构成回路if(m!=n){//没有构成回路ends[m]=n;//设置m在"已有最小生成树"中的终点 <E,F>[0,0,0,0,5,0,0,0,0,0,0,0]rets[index++]=edges[i];//有一条边加入到rets数组}}//统计并打印最小生成树,输入retsSystem.out.println("最小生成树为");for (int i = 0; i < index; i++) {System.out.println(rets[i]);}}//打印邻接矩阵public void print() {System.out.println("邻接矩阵为:");for (int i = 0; i < vertexs.length; i++) {for (int j = 0; j < vertexs.length; j++) {System.out.printf("%10d\t", matrix[i][j]);}System.out.println();}}//对边进行排序处理,冒泡排序/*** @param edges 边的集合*/private void sortEdges(EData[] edges) {for (int i = 0; i < edges.length-1; i++) {for (int j = 0; j < edges.length - 1 - i; j++) {if (edges[j].weight > edges[j + 1].weight) {EData temp = edges[j];edges[j] = edges[j+1];edges[j+1] = temp;}}}}/*** @param ch 顶点的值,比如'A','B'* @return 返回的是ch顶点对应的下标,如果找不到,返回-1*/private int getPosition(char ch) {for (int i = 0; i < vertexs.length; i++) {if (vertexs[i] == ch) {//找到return i;}}//找不到,返回-1return -1;}/*** 获取图中的边,放到EData[]中,后面我们需要遍历该数组* 是通过matrix邻接矩阵来获取* EData 形式[['A','B',12],['B','F',7]...]** @return*/private EData[] getEdges() {int index = 0;EData[] edges = new EData[edgNum];for (int i = 0; i < vertexs.length; i++) {for (int j = i + 1; j < vertexs.length; j++) {if (matrix[i][j] != INF) {edges[index++] = new EData(vertexs[i], vertexs[j], matrix[i][j]);}}}return edges;}/*** 功能:获取下标为i的顶点的终点,用于后面判断两个顶点的终点是否相同* @param ends:数组就是记录了各个顶点对应的终点是哪个,ends数组是在遍历过程中,逐步形成的* @param i 表示闯入的顶点对应的下标* @return 返回的就是下标为i的这个顶点对应的终点的下标*/private int getEnd(int[] ends,int i){while (ends[i]!=0){i=ends[i];}return i;}}//创建一个类EData,它的对象实例就是表示一条边
class EData {char start;//边的一个点char end;//边的另外一个点int weight;//边的权值//构造器public EData(char start, char end, int weight) {this.start = start;this.end = end;this.weight = weight;}//重写toString方法,便于输出边的信息@Overridepublic String toString() {return "EData{" +"start=" + start +", end=" + end +", weight=" + weight +'}';}
}

克鲁斯卡尔算法(公交站问题)相关推荐

  1. 克鲁斯卡尔算法学习(Java)

    克鲁斯卡尔算法学习(Java) 学习视频:尚硅谷韩老师java讲解数据结构和算法 一.应用场景-公交站问题 某城市新增 7 个站点(A, B, C, D, E, F, G) ,现在需要修路把 7 个站 ...

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

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

  3. 克鲁斯卡尔算法解决公交站问题

    一 问题提出 1 某城市新增7个站点(A, B, C, D, E, F, G) ,现在需要修路把7个站点连通. 2 各个站点的距离用边线表示(权) ,比如 A – B 距离 12公里. 问:如何修路保 ...

  4. KruskalAlgorithm(克鲁斯卡尔算法)

    KruskalAlgorithm介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择 n-1 条边,并保证这 n-1 条边不构成回路 具 ...

  5. 克鲁斯卡尔算法的基本介绍和实现方法(Java)

    克鲁斯卡尔(Kruskal)算法介绍: 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路 具体做法 ...

  6. 克鲁斯卡尔算法(Kruskal)详解

    应用场景-公交站问题 看一个应用场景和问题: 1)某城市新增7个站点(A, B, C, D, E, F, G) ,现在需要修路把7个站点连通 2)各个站点的距离用边线表示(权) ,比如 A – B 距 ...

  7. 算法6:克鲁斯卡尔算法

    目录 1. 应用场景-公交站问题 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解说明 3.1 克鲁斯卡尔算法图解 3.2 克鲁斯卡尔算法分析 3.3 如何判断是否构成回路 4. 代码实现 1. 应 ...

  8. 普利姆算法和克鲁斯卡尔算法解决最小生成树问题

    什么是最小生成树? 最小生成树(Minimum Cost Spanning Tree),简称MST. 最小生成树要求图是连通图.连通图指图中任意两个顶点都有路径相通,通常指无向图.理论上如果图是有向. ...

  9. 算法其实很简单—克鲁斯卡尔算法

    目录 1. 克鲁斯卡尔算法介绍 2. 公交站问题 2.1 克鲁斯卡尔算法图解 2.2 克鲁斯卡尔算法分析 2.3 如何判断是否构成回路 3. 代码实现 1. 克鲁斯卡尔算法介绍 1)克鲁斯卡尔(Kru ...

最新文章

  1. Android自定义属性 format详解
  2. C代码+汇编 C的for汇编学习分析
  3. 01:操作系统(centos,redhat):性能监控和网络命令
  4. 5年财务老员工:早发现这个报表工具,也不会因为加班凄凉辞职
  5. 防数据泄密:是否应实施“多重认证”?
  6. 特征工程之自动特征生成(自动特征衍生)工具Featuretools介绍
  7. PHP使用CodeIgniter笔记
  8. Android Studio使用tips
  9. Ubuntu下好用的小工具
  10. 自然语言处理简明教程——序言、第一章
  11. ubuntu16.04 系统ghostscript 缺少中文语言包导致字体重叠问题
  12. TSP问题-简介与部分解法
  13. xp系统服务器找不到打印机无法连接失败,xp系统打印机共享提示连接失败的解决方法...
  14. Axure中继器使用
  15. 搜狗浏览器怎么翻译英文网页
  16. 可用于保健食品的中药名单,卫生部关于进一步规范保健食品原料管理的通知...
  17. 汉诺塔问题及时间复杂度推导
  18. win7任务栏计算机怎么显示桌面,在win7任务栏添加一个显示桌面的图标按钮的方法...
  19. Nature综述:Rob Knight手把手教你分析菌群数据(全文翻译1.8万字)
  20. grafana-汉化方法

热门文章

  1. Java线程问题问答
  2. ICPC 南昌现场赛 K:Tree(dsu on tree + 动态开点线段树)
  3. Polynomial(2019南昌邀请赛)(拉格朗日插值)
  4. P5488 差分与前缀和(多项式/生成函数)
  5. 【ROI 2019 Day2】课桌【贪心】【决策单调性】【分治】
  6. 牛客练习赛74 D CCA的图
  7. P3178 [HAOI2015]树上操作
  8. Codeforces Round #759 (Div. 2, based on Technocup 2022 Elimination Round 3)
  9. [SDOI2012]吊灯(结论)
  10. CF1322B:Present(异或、two pointers)