图 - Java实现无向带权图的邻接矩阵表示法

2023-11-19

图 - Java实现无向带权图的邻接矩阵表示法

1.图

1.1 图的介绍

  • 图(Graph),是一种复杂的非线性表结构
  • 图中的元素我们就叫做顶点(vertex)
  • 图中的一个顶点可以与任意其他顶点建立连接关系。我们把这种建立的关系叫做边(edge),跟顶点相连接的边的条数叫做度(degree)
  • 这是一个无向带权图:
    在这里插入图片描述

1.2 邻接矩阵的介绍

  • 图最直观的一种存储方法就是,邻接矩阵(Adjacency Matrix)

  • 邻接矩阵的底层是一个二维数组
    在这里插入图片描述

A B C D E F
A 0 1 1 1 0 0
B 1 0 0 1 0 0
C 1 0 0 0 1 1
D 1 1 0 0 1 1
E 0 0 1 1 0 1
F 0 0 1 1 1 0
  • 带权图:数组中就存储相应的权重
    在这里插入图片描述
1 2 3 4
1 0 5 3 0
2 0 0 1 6
3 3 2 0 1
4 0 6 1 0

2.Java实现无向带权图邻接矩阵表示法的常见功能

package com.lagou;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author 云梦归遥
 * @date 2022/5/20 12:30
 * @description 无向带权图 - 邻接矩阵法
 */
public class NoDirectionWeightTuMethod {
    private List<Object> nodeList; // 存储所有节点的集合
    private int[][] adjacencyMatrix; // 邻接矩阵
    private int edge; // 边的数量

    public NoDirectionWeightTuMethod(int num){
        nodeList = new ArrayList<>(num);
        adjacencyMatrix = new int[num][num];
        edge = 0;
    }

    // 添加节点
    public NoDirectionWeightTuMethod insert(Object node){
        nodeList.add(node);
        return this;
    }

    // 查找节点
    public String select(Object node){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("【" + node + "】= ");
        int index = nodeList.indexOf(node); // 获取索引
        if (index >= 0){
            // 节点存在
            for (int i = 0; i < adjacencyMatrix.length; i++){
                if (adjacencyMatrix[index][i] > 0){
                    stringBuilder.append("【<" + node + ", " + nodeList.get(i) + "> - weight: " + adjacencyMatrix[index][i] + "】 => ");
                }
            }
        } else {
            stringBuilder.append("null");
        }
        String result = stringBuilder.toString();
        result = result.substring(0, result.lastIndexOf(" => "));
        return result;
    }

    // 获取节点的个数
    public int getNodeNum(){
        return nodeList.size();
    }

    // 添加边(权重)
    public NoDirectionWeightTuMethod addEdge(Object object1, Object object2, int weight){
        if (nodeList.contains(object1) && nodeList.contains(object2)){
            int index1 = nodeList.indexOf(object1);
            int index2 = nodeList.indexOf(object2);
            adjacencyMatrix[index1][index2] = weight;
            adjacencyMatrix[index2][index1] = weight;
        }
        return this;
    }

    // 获取权重
    public int getWeight(Object object1, Object object2){
        int result = Integer.MAX_VALUE; // 默认 int 最大值
        if (nodeList.contains(object1) && nodeList.contains(object2)){
            int index1 = nodeList.indexOf(object1);
            int index2 = nodeList.indexOf(object2);
            result = adjacencyMatrix[index1][index2];
        }
        return result;
    }

    // 判断边是否存在
    public boolean hasEdge(Object object1, Object object2){
        boolean result = false;
        if (nodeList.contains(object1) && nodeList.contains(object2)){
            int index1 = nodeList.indexOf(object1);
            int index2 = nodeList.indexOf(object2);
            if (adjacencyMatrix[index1][index2] > 0){
                result = true;
            }
        }
        return result;
    }

    // 获取边的数量
    public int getEdgeNum(Object object){
        int num = Integer.MAX_VALUE;
        if (nodeList.contains(object)){
            num = 0;
            int index = nodeList.indexOf(object);
            for (int i = 0; i < adjacencyMatrix.length; i++){
                if (adjacencyMatrix[index][i] > 0){
                    num++;
                }
            }
        }
        return num;
    }

    // 获取 邻接矩阵
    public String getAdjacencyMatrix(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("  " + Arrays.toString(nodeList.toArray()) + "\n");
        for (int i = 0; i < adjacencyMatrix.length; i++){
            stringBuilder.append(nodeList.get(i) + " " + Arrays.toString(adjacencyMatrix[i]) + "\n");
        }
        return stringBuilder.toString();
    }
}

进行测试

package com.lagou.test;

import com.lagou.NoDirectionWeightTuMethod;

/**
 * @author 云梦归遥
 * @date 2022/5/20 13:05
 * @description
 */
public class NoDirectionWeightTuMethodTest {
    public static void main(String[] args) {
        NoDirectionWeightTuMethod weightTuMethod = new NoDirectionWeightTuMethod(5);
        weightTuMethod.insert("A").insert("B").insert("C").insert("D").insert("E"); // 链式调用
        weightTuMethod
                .addEdge("A", "B", 3) // 链式调用
                .addEdge("A", "D", 1)
                .addEdge("A", "E", 5)
                .addEdge("B", "C", 2)
                .addEdge("D", "E", 7)
                .addEdge("C", "D", 3);
        System.out.println("是否存在边:" + weightTuMethod.hasEdge("A", "D"));
        System.out.println("边的权重:" + weightTuMethod.getWeight("A", "D"));
        System.out.println("边的数量:" + weightTuMethod.getEdgeNum("A"));
        System.out.println("A 的所有关系:" + weightTuMethod.select("A"));
        System.out.println("图中节点个数:" + weightTuMethod.getNodeNum());
        System.out.println("整个图的邻接矩阵:");
        System.out.println(weightTuMethod.getAdjacencyMatrix());
    }
}

在这里插入图片描述

3.总结

  • 无向带权图的邻接矩阵表示法主要是通过二维数组来实现的
  • 每个行与列的交点存储的值其实是对应边上的权重
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图 - Java实现无向带权图的邻接矩阵表示法 的相关文章

  • 编写潜在并发问题的证明

    我正在阅读 Java 并发实践 并尝试编写一段代码来表明第 3 5 1 章中作为示例提供的类确实会引入问题 public class Holder public int n public Holder int n this n n publ
  • 由于保存之前/之后的 CSV 差异而导致错误解析(Java w/ Apache Commons CSV)

    我有一个 37 列的 CSV 文件 我正在使用 Apache Commons CSV 1 2 在 Java 中解析该文件 我的设置代码如下 initialize FileReader object FileReader fileReader
  • 为什么需要使用java.util.TimerTask的purge()?

    Timer cancel 取消任务 Timer purge 从此计时器的任务队列中删除所有已取消的任务 如果我不在这里使用 purge 会发生什么 当计时器的任务队列已满时会发生什么 除非您正在运行的计时器数量过多 否则实际计时器行为不会发
  • 访问 java jigsaw 模块中的资源文件[重复]

    这个问题在这里已经有答案了 我正在尝试从项目中的类访问 Eclipse 项目中的文件 我需要将该项目声明为 jigsaw 模块才能从其他项目访问它 但是通过这样做 我无法再访问项目中的 example png 等文件 这是我的项目结构 pr
  • MySQL 中电话号码的最佳数据类型是什么?它的 Java 类型映射应该是什么?

    我正在将 MySQL 与 Spring JDBC 模板一起用于我的 Web 应用程序 我需要存储仅包含数字的电话号码 10 我对使用数据类型的数据类型有点困惑 MySQL 中最适合它的数据类型是什么 为此 Bean POJO 类中的 Jav
  • 无法在 Spring boot 中使用 findOne() 方法

    我的项目是关于用户管理器网络的 我是 Spring 和 Java 的新手 这是我的代码 在 UserController 中 RequestMapping value users name method RequestMethod GET
  • spring启动时如何加载@Cache?

    我正在使用 spring cache 来改进数据库查询 其工作原理如下 Bean public CacheManager cacheManager return new ConcurrentMapCacheManager books Cac
  • 运行Java程序时出错

    我正在尝试使用 netbeans 运行我的 java 程序 但收到此错误 有什么建议吗 Exception in thread AWT EventQueue 0 java lang NullPointerException at javax
  • java.util.Objects 与Optional 哪个更可取?

    The java util Objects http download java net java jdk9 docs api java util Objects html类通过许多新方法进行了扩展 对象 requireNonNullEls
  • 带有 CONTAINS 查询的PreparedStatement

    我有一个查询需要连续运行 28000 次 所以我认为使用准备好的语句可能是一个聪明的主意 这是我的查询 String requestWithFirstName SELECT SE ELEMENT ID SE LASTNAME SE FIRS
  • 如何在 groovy 中将输出重定向到 stderr?

    我正在寻找一种将 groovy 脚本中的输出重定向到 stderr 的方法 catch Exception e println Want this to go to stderr 就在我的脑海中 你不能做一些自我接线吗 def printE
  • 如何找到类路径上具有特定方法注释的所有类?

    我想在Java中实现一个基于注释的初始化机制 具体来说 我定义了一个注释 Retention RetentionPolicy RUNTIME Target ElementType METHOD public interface Initia
  • java POI XSSF 公式评估器

    我在保存新的 Excel 文件时遇到问题 我希望当它被保存时 公式会自行计算 但目前它只是返回 Excel 文件中的一个字符串 公式是正确的 我不知道到底要得到FormulaEvaluator上班 这是我输入返回字符串的公式的地方 data
  • java:验证 GUI 中的所有文本字段是否已完成

    我正在尝试创建一个允许某人设置帐户的 GUI 我想验证按下创建帐户按钮时所有文本字段是否完整 做这个的最好方式是什么 我正在附加我的代码 但我对文本字段是否完整的验证不起作用 参见下面的代码 public class GUIaccounts
  • 更改 Logger 实例的全局设置

    我在用着java util logging Logger http download oracle com javase 1 4 2 docs api java util logging Logger html作为我的应用程序的日志引擎 每
  • 使用 System.currentTimeMillis() 每秒运行一次代码

    我试图使用 System currentTimeMillis 每秒运行一行代码 代码 while true long var System currentTimeMillis 1000 double var2 var 2 if var2 1
  • 如何为 Weblogic 10.3.6 启用 Java 持久性 2.0

    我正在使用 eclipse 和 weblogic 服务器 为了将项目添加到 weblogic 服务器 它需要支持 Java Persistance 2 0 但是当尝试安装它时 我不断收到此消息 在 Weblogic Server 安装中启用
  • hibernate通过主键查询

    我想通过主键创建查询 假设我有类主键 PersonKey 属性是 name 和 id 我有 Person 类 属性是 PersonKey 地址 DOB 现在 我想通过主键搜索人员 首先 我创建 PersonKey 的实例 并将名称设置为 j
  • 在 Eclipse Testrunner 中使用名称的 ParameterizedTest

    当您使用 Eclipse TestRunner 运行 JUnit 4 ParameterizedTest 时 图形表示相当愚蠢 对于每个测试 您都有一个名为 0 1 ETC 是否可以进行测试 0 1 等显式名称 实施一个toString测试
  • 我可以在方法体内使用注释吗?

    允许 Java 注释的语义将它们放置在某处在函数体内 例如注释特定的函数调用 语句或表达式 例如 class MyClass void theFunc Thing thing String s null Catching NullPoint

随机推荐

  • Java实体类转Map、Map转实体类

    1 创建entity User java package com jeff entity public class User private String userName private String password private I
  • Python错误处理的艺术:使用retrying库实现高效重试机制

    简介 学习如何使用 Python 的 retrying 库来处理在程序运行过程中可能出现的各种异常和错误 retrying 是一种简单 易于使用的重试机制 帮助我们处理由网络问题或其他暂时性错误引起的失败 在很多情况下 简单的重试可能就是解
  • SSM框架运行原理

    ssm框架 包括 springMVC spring mybatis springMVC 是基于MVC的框架 属于MVC框架的还有 Struts1 Struts2 SpringMVC 获取值得方式 Struts1 actionForm jav
  • SylixOS学习三—— SylixOS的引导与安装1

    自学SylixOS启程之旅笔记 一 SylixOS 引导过程分析 1 SylixOS 常用引导程序 2 SylixOS 支持ARM设备的几种引导方式 3 SylixOS引导过程分析 总流程分析 3 1 一个设备从上电到启动完成的整个流程 3
  • 使用两个队列实现一个栈,使用两个栈实现一个队列

    一 栈与队列的特点 一 栈 栈 一种特殊的线性表 其只允许在固定的一端进行插入和删除元素操作 进行数据插入和删除操作的一端称为栈顶 另一端称为栈底 不含任何元素的栈称为空 栈 栈又称为后进先出的线性表 栈的特点 后进先出 LIFO 二 队列
  • Java ZipOutputStream 的使用,实现压缩文件

    Java 压缩文件主要通过 ZipOutputStream 实现 ZipOutputStream 有 5 个关键的方法 putNextEntry 向压缩包中添加子文件 并设置文件路径和名称 压缩包解压后得到的文件叫子文件 该方法接受一个 Z
  • Flask框架十:Flask终章与补充(首)

    1 WTForms的表单验证 form表单验证的类型有多种 邮箱 年龄 是否为空等多种验证 以及验证码等验证 WTForms都提供了相关的验证模块 创建一个froms模块 将想要验证的视图模块中的内容写在类里面 from wtforms i
  • 如果我想用vue来对导入的word文件进行解析呢

    如果你想使用 Vue 来解析 Word 文件 你可以考虑使用第三方库来帮助你完成这个任务 你可以使用 js word library 来解析 Word 文件 它是一个 JavaScript 库 可以解析 Word 文件中的文本 图像 表格等
  • GIF演示排序算法

    最近在准备笔试 面试 看了不少关于排序算法的知识 总感觉代码有余 直观不足 所以想利用直观的GIF动图来演示各种排序算法 1 插入排序 Insertion Sort 1 1算法简介 插入排序 Insertion Sort 的算法描述是一种简
  • CentOS7的firewall和安装iptables

    前言 CentOS7 的防火墙默认使用是firewall 而我们通常使用iptables 本文记录了firewall基础的命令和iptables的安装和使用 firewall部分 part1 服务命令 systemctl start fir
  • 简析多级指针解引用

    转自 简析多级指针解引用 指针是C语言中公认的最为强大的语法要素 但同时也是最难理解的语法要素 它曾给程序员带来了无数麻烦和痛苦 以致于在C语言之后诞生的很多新兴 语言中我们再也难觅指针的身影了 下面是一个最简单的C语言指针的例子 int
  • hadoop使用(五)

    博客园 闪存 首页 新随笔 联系 管理 订阅 随笔 247 文章 122 评论 571 hadoop使用 五 第1章 引言 1 1 编写目的 对关于hadoop的文档及资料进行进一步的整理 1 2 相关网站 毋庸置疑 http hadoop
  • 查看3306端口被谁占用

    今天安装mysql一直有问题 怀疑3306被谁占用了 排查开始 一 使用命令符netstat命令查看 netstat a n 显示各个端口占用 netstat ano 显示各个端口占用和进程PID 二 使用netstat aon finds
  • 虚拟机无敌大坑,安装不了cuda和cudnn

    大家好 想用虚拟机装cuda和cudnn这两个环境 如果需要的话不要在虚拟机中装 根本装不好 踩了两天的坑 才知道在虚拟机环境下是无法安装cuda和cudnn得 因为虚拟机环境下根本无法识别到你的显卡版本 只有一个虚拟机得环境 所以如果想安
  • 在eclipse的Server里找不到Apache tomcat的解决方案

    我们在创建Dynamic Web Project时在新界面一栏中 Target runtime一栏是空 没有可选择的tomcat 点击右侧的New Runtime后看到如图没有对应的Apache 同样我们在上面的windows gt pre
  • RK3588 添加ROOT权限

    一 ROOT简介 ROOT权限是Linux和Unix系统中的超级管理员用户帐户 该帐户拥有整个系统的最高权利 可以执行几乎所有操作 ROOT就是获取安卓系统中的 最高用户权限 以便执行一些需要高权限才能执行的操作 包括卸载系统自带程序 刷机
  • openswan pluto代码分析--(1)pluto简介

    pluto简介 pluto是一个openswan中的守护进程 提供IKEv1服务 Pluto通信消息 网卡数据报文消息 whack命令的消息 内核通信消息 接下来分别介绍上面三种通信消息 1 网卡数据报文消息 打开UDP500和4500端口
  • Windows Teams - Visual Studio Code 初始化工程

    使用VIsual Studio Code 在clone完Teams的demo的代码 执行gulp命令的时候报错 gulp File C Users XXX AppData Roaming npm gulp ps1 cannot be loa
  • 硬件基础之继电器

    一 技术理论 继电器 Relay 是一种电子控制器件 它具有控制系统 又称输入回路 和被控制系统 又称输出回路 通常应用于自动控制电路中 它实际上是用较小的电流去控制较大电流的一种 自动开关 如下图 因为继电器是由线圈和触点两部分组成 所以
  • 图 - Java实现无向带权图的邻接矩阵表示法

    图 Java实现无向带权图的邻接矩阵表示法 1 图 1 1 图的介绍 图 Graph 是一种复杂的非线性表结构 图中的元素我们就叫做顶点 vertex 图中的一个顶点可以与任意其他顶点建立连接关系 我们把这种建立的关系叫做边 edge 跟顶