java 最小生成树_图的最小生成树(java实现)

1.图的最小生成树(贪心算法)

我两个算法的输出都是数组表示的,当前的索引值和当前索引对应的数据就是通路,比如parent[2] = 5;即2和5之间有一个通路,第二个可能比较好理解,第一个有点混乱

是什么?

将一个有权图中的 所有顶点都连接起来,并保证连接的边的 总权重最小,即最小生成树,最小生成树不唯一

为什么?

传入邻接矩阵,返回可以生成最小生成树的数据

我们有两种方式生成图的最小生成树1.普里姆(Prim)算法2.克鲁斯卡尔(Kruskal)算法

怎样做?

下面是普里姆算法的最小生成树

027a2b21cdaec017cf02fc8982b37a32.png

下面是克鲁斯卡尔算法的最小生成树:

bedb53884cbe8a5baf2c5c0bbed2fa70.png

图的邻接矩阵表示法(无向图,上三角矩阵)

int[][] arr = new int[][]{

{-1, 4, 0, 0, 0, 0, 0, 8, 0},

{0, -1, 8, 0, 0, 0, 0, 11, 0},

{0, 0, -1, 7, 0, 4, 0, 0, 2},

{0, 0, 0, -1, 9, 14, 0, 0, 0},

{0, 0, 0, 0, -1, 10, 0, 0, 0},

{0, 0, 0, 0, 0, -1, 2, 0, 0},

{0, 0, 0, 0, 0, 0, -1, 1, 6},

{0, 0, 0, 0, 0, 0, 0, -1, 7},

{0, 0, 0, 0, 0, 0, 0, 0, -1}

};

1.普里姆算法(加点法)

需求:求出最小生成树的权值

输入参数:二维数组arr(邻接矩阵),列表list(存放已经被加入的点),整型sum(存放权值)

输出参数:整型数组parent

1)先找一个起点,这个起点为任意一点,放入list中2)如果list中不包含全部节点,进入循环1>遍历list中节点,查找不存在list中的邻接节点的最小值,记录下begin和end2>将begin和end放入数组中,较小值节点赋值给较大值所在数组位置

3)返回parent

实现:

importjava.util.ArrayList;importjava.util.Arrays;importjava.util.List;/*** 普里姆(Prim)算法

*

*@authorXiong YuSong

* 2019/3/22 16:02*/

public classPrim {public static voidmain(String[] args) {int[][] arr = new int[][]{

{-1, 4, 0, 0, 0, 0, 0, 8, 0},

{0, -1, 8, 0, 0, 0, 0, 11, 0},

{0, 0, -1, 7, 0, 4, 0, 0, 2},

{0, 0, 0, -1, 9, 14, 0, 0, 0},

{0, 0, 0, 0, -1, 10, 0, 0, 0},

{0, 0, 0, 0, 0, -1, 2, 0, 0},

{0, 0, 0, 0, 0, 0, -1, 1, 6},

{0, 0, 0, 0, 0, 0, 0, -1, 7},

{0, 0, 0, 0, 0, 0, 0, 0, -1}

};

List list = new ArrayList<>();//先将0放置在list中

list.add(0);int begin = 0, end = 0, weight;int[] parent = new int[arr.length];for (int i = 0; i < arr.length; i++) {

parent[i]= -1;

}while (list.size()

weight=Integer.MAX_VALUE;for(Integer row : list) {for (int i = 0; i < arr.length; i++) {if (!list.contains(i)) {if (i >= row + 1) {if (arr[row][i] > 0 && arr[row][i]

begin=row;

end=i;

weight=arr[row][i];

}

}else if (i <= row - 1) {//我这里只用了上三角矩阵,所以这里需要画蛇添足写这一部分

if (arr[i][row] > 0 && arr[i][row]

begin=row;

end=i;

weight=arr[i][row];

}

}

}

}

}

list.add(end);

parent[end]=begin;

}

System.out.println(Arrays.toString(parent));

}

}

2.克鲁斯卡尔算法(加边法)

需求:求出最小生成树的权值

构建类:Edge三元组,根据weight(权值)排序

输入参数:存放有Edge的列表list,并查集parent

输出参数:并查集parent(最小生成树的数组表现形式)

原理:贪心算法的实现,程序中使用了并查集(判断两个集合中是否存在相同的数据)这种特殊的数据结构,使用数组实现

1)创建一个三元组,将邻接矩阵中数据放入三元组中,再放入list中,根据权值进行排序2)创建变量count=0,整型数组parent3)如果list中还存在值,则进行循环1>判断begin和end是否存在于不同的集合中(判断是否在同一棵树中,即判断当前节点在并查集parent中的根节点是否为同一个)2>如果存在不同的集合中,则将较小值节点赋值给较大值所在数组位置,较小值节点为较大值节点的父节点4)返回parent

实现:

importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Collections;importjava.util.List;/***@authorXiong YuSong

* 2019/3/22 17:04*/

class Edge implements Comparable{//起始点

private intbegin;//终止点

private intend;//权值

private intweight;public Edge(int begin, int end, intweight) {this.begin =begin;this.end =end;this.weight =weight;

}public intgetBegin() {returnbegin;

}public void setBegin(intbegin) {this.begin =begin;

}public intgetEnd() {returnend;

}public void setEnd(intend) {this.end =end;

}public intgetWeight() {returnweight;

}public void setWeight(intweight) {this.weight =weight;

}

@Overridepublic intcompareTo(Edge o) {if (o.weight > this.weight) {return -1;

}else{return 1;

}

}

}public classKruskal {public static voidmain(String[] args) {

//默认以a为根节点的最小生成树

List list = new ArrayList<>();int[][] arr = new int[][]{

{-1, 4, 0, 0, 0, 0, 0, 8, 0},

{0, -1, 8, 0, 0, 0, 0, 11, 0},

{0, 0, -1, 7, 0, 4, 0, 0, 2},

{0, 0, 0, -1, 9, 14, 0, 0, 0},

{0, 0, 0, 0, -1, 10, 0, 0, 0},

{0, 0, 0, 0, 0, -1, 2, 0, 0},

{0, 0, 0, 0, 0, 0, -1, 1, 6},

{0, 0, 0, 0, 0, 0, 0, -1, 7},

{0, 0, 0, 0, 0, 0, 0, 0, -1}

};for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i][j] > 0) {

list.add(newEdge(i, j, arr[i][j]));

}

}

}

Collections.sort(list);//数组中每一个节点都只知道他的父节点是什么,-1表示不存在父节点,0位置是根节点

int[] parent = new int[arr.length];for (int i = 1; i < arr.length; i++) {

parent[i]= -1;

}int m = 0, n = 0;for(Edge edge : list) {//寻找这两个点有没有相同的父节点

m =find(parent, edge.getBegin());

n=find(parent, edge.getEnd());if (m !=n && parent[edge.getEnd()]>0) {

parent[edge.getEnd()]=edge.getBegin();

}

}

System.out.println(Arrays.toString(parent));

}private static int find(int[] parent, intch) {while (parent[ch] > 0) {

ch=parent[ch];

}returnch;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中文分词工具 java_java读取中文分词工具(一)

import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.RandomAccessFile;import java.util.StringTokenizer;/** 文本格式&#xff1a;已分词的中文文本&#xff0…

java中的成员变量和局部变量的区别_java中成员变量与局部变量区别分析

本文实例分析了java中成员变量与局部变量区别。分享给大家供大家参考。具体分析如下&#xff1a;成员变量&#xff1a;在这个类里定义的私有变量&#xff0c;属于这个类。创建以及使用成员变量public class Person {String name;String Sex;int age;double Height;public stati…

java 自定义注解 生成json_用自定义注解实现fastjson序列化的扩展

这篇文章起源于项目中一个特殊的需求。由于目前的开发方式是前后端分离的&#xff0c;基本上是通过接口提供各个服务。而前两天前端fe在开发中遇到了一些问题&#xff1a;他们在处理字符串类型的时间时会出现精度丢失的情况&#xff0c;所以希望后台是以时间戳的形式返回给前端…

工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)

简单工厂不是一个标准的设计模式&#xff0c;但是它实在是太常用了&#xff0c;简单而又神奇&#xff0c;所以还是需要好好掌握的&#xff0c;就当是对学习设计模式的热身运动吧。为了保持一致性&#xff0c;我们尽量按照学习其它模式的步骤来进行学习。1 场景问题大家都知道&…

java asm jndi_GitHub - Q1ngShan/JNDI: JNDI 注入利用工具

JNDI 注入利用工具介绍本项目为 JNDI 注入利用工具&#xff0c;生成 JNDI 连接并启动后端相关服务&#xff0c;可用于 Fastjson、Jackson 等相关漏洞的验证。本项目是基于 welk1n 的 JNDI-Injection-Exploit&#xff0c;在此项目的基础服务框架上&#xff0c;重新编写了攻击利用…

java保存登录信息_java – 保存登录详细信息(首选项)android

我有一个具有登录,注销功能的Android应用程序.登录表单包含用户名和密码以及登录按钮.我想在用户选中“记住我”复选框时保存用户名和密码.我的project.java文件如下所示&#xff1a;public class project extends Activity {private static final int IO_BUFFER_SIZE 4 * 102…

java堆和非堆_java 堆与非堆 内存

堆(Heap)和非堆(Non-heap)内存按照官方的说法&#xff1a;“Java 虚拟机具有一个堆&#xff0c;堆是运行时数据区域&#xff0c;所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主…

java中fis和fos_java中-的流-与操作

/*字节输出流 OutputStrema&#xff1a;* OutputStream抽象类* write(int b); 将指定的字节写入此流中* write(byte[] b); 将指定的数组 输入此流中* write(byte[] b , int a , int c); 将指定的数组输入此流中 从a索引开始 获取c 个* close(); 将此流关闭 并释放资源* fl…

java 上传文件及预览_SpringBoot上传下载文件及在线预览

SpringBoot上传下载文件及在线预览今天大概就说说如何使用SpringBoot进行上传和下载以及在线预览文件 本篇主要介绍上传下载的功能&#xff0c;对于界面就简单一点&#xff0c;大致如下&#xff1a;一、老规矩还是先看看小项目的目录结构&#xff1a;二、添加对应的pom依赖org.…

yolov4用1050ti_简单粗暴的多目标跟踪神器 – DeepSort

目标跟踪问题一直是计算机视觉的热点任务之一&#xff0c;简单的可以分为单目标跟踪与多目标跟踪&#xff0c;最常见的目标跟踪算法都是基于检测的跟踪算法&#xff0c;首先发现然后标记&#xff0c;好的跟踪算法必须具备REID的能力。今天小编斗胆给大家推荐一个结合传统算法跟…

java 数据库语句_java连接各数据库的语句

1、Oracle8/8i/9i数据库(thin模式)Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();String url"jdbc:oracle:thin:localhost:1521:orcl";//orcl为数据库的SIDString user"test\";String password"test";Connection c…

alm数据库mysql_mysql

1. mysql启动mysqld --console2. mysql关闭mysqladmin shutdown -uroot -proot3. 免安装mysql配置&#xff1a;启动mysql&#xff1a; mysqld --skip-grant-tables(跳过安全校验)&#xff0c; 修改mysql.user表里面的数据&#xff0c;最后flush privileges;mysql jdbc连接代码…

类java的步骤_java类加载的过程

类加载就是三个过程&#xff1a;加载、链接、初始化链接又可以分为验证、准备、解析1.加载将class字节码文件通过类加载器装入内存中2.验证确保当前class文件的字节流所包含的内容符合当前JVM的规范要求&#xff0c;并且不会出现危害JVM自身安全的代码&#xff0c;当前字节流不…

java拓展接口_Java拓展接口-default关键词

Java接口在使用过程中有两点规定&#xff1a;1、接口中只能有定义方法名、方法返回类型&#xff0c;不能有方法的实现。2、实现接口的类&#xff0c;必须实现接口中所有的方法。例如下面的例子&#xff1a;//定义接口public interface Action {//接口中的方法定义&#xff0c;只…

java编写通信录管理系统_Java 实现通讯录管理系统教程

本文实例为大家分享了java实现通讯录管理系统的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下完成项目的流程&#xff1a;1.根据需求&#xff0c;确定大体方向2.功能模块分析3.界面实现4.功能模块设计5.coding6.代码测试下面是源代码&#xff1a;import java.awt.Co…

java姑娘_初识java这个小姑娘(二)

正版疯狂java讲义第5版编程教材76.5元(需用券)去购买 >妙解垃圾回收机制周一&#xff0c;早高峰&#xff01;&#xff01;&#xff01;五个字&#xff0c;说尽心中的绝望&#xff01;&#xff01;&#xff01;一段考验一个人耐力、智力、开车技术以及脾气的路。 我把车开进了…

JAVA script 循环 图片_深入分析JavaScript 事件循环(Event Loop)

事件循环(Event Loop)&#xff0c;是每个JS开发者都会接触到的概念&#xff0c;但是刚接触时可能会存在各种疑惑。众所周知&#xff0c;JS是单线程的&#xff0c;即同一时间只能运行一个任务。一般情况下这不会引发问题&#xff0c;但是如果我们有一个耗时较多的任务&#xff0…

mysql update 跳过重复_MySQL通过UPDATE / DELETE整合重复的数据记录

我有一个看起来像这样的表&#xff1a;mysql> SELECT * FROM Colors;╔════╦══════════╦════════╦════════╦════════╦════════╦════════╦════════╗║ ID ║ USERNAME ║ RED ║ GREEN ║ YELLOW ║ …

java目录实用工具_JAVA 创建文件和文件夹,删除文件和文件夹的实用工具

package com.file;import java.io.File;import java.io.IOException;//创建新文件和目录public class CCRDFile {// 验证字符串是否为正确路径名的正则表达式private static String matches "[A-Za-z]:\\\\[^:?\">// 通过 sPath.matches(matches) 方法的返回值判…

java 方法重载的作业_java第六章 方法及方法重载 课堂笔记、作业

当参数传递为基本数据类型时&#xff0c;参数变化不保留&#xff0c;基本数据类型参数传值当参数传递为引用数据类型时&#xff0c;参数变化会保留&#xff0c;引用数据类型参数传址//基本数据类型在别处被重新赋值&#xff0c;则本体不受影响&#xff0c;其值不变//引用型数据…