图的结构模板及遍历

news2024/11/28 10:49:09

图:由点的集合和边的集合组成。

常用的表示图的方法有两种:
1、邻接表法

将一个点的邻居都列出来。有向图只列出从这个点出发向外发散的点

2、邻接矩阵法

将点集列出一列行,列出一列列,在矩阵中填两点之间的权值(距离)

【精选】数据结构:图(Graph)【详解】_数据结构图_UniqueUnit的博客-CSDN博客

解图有关的题目的思路:

图有很多表达方式,我们通常都是 先将图转化为熟悉的表达方式,再实现算法

图结构模板
package graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class Graph {
    public HashMap<Integer, Node> nodes;//点集:编号、点
    public HashSet<Edge> edges;//边集:边

    public Graph() {
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }


}

class Node {
    public int value;//数据
    public int in;//入度
    public int out;//出度
    public ArrayList<Node> nexts;//对有向图,从当前这个点出发发散的直接邻居的点
    public ArrayList<Edge> edges;//对有向图,发散出去的边属于这个点,指向进来的边则不属于这个点

    public Node(int value) {
        this.value = value;
        in = 0;
        out = 0;
        nexts = new ArrayList<>();
        edges = new ArrayList<>();
    }
}

class Edge {
    public int weight;//权值
    public Node from;//边的起点
    public Node to;//边的终点

    public Edge(int weight, Node from, Node to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }
}

其他图的方式转化为此结构示例

原来的表达方式

权值weight始节点from末节点to
501
312
702
package graph;

public class Transmit {
    //matrix矩阵,n*3,[weight,from,to]
    public static Graph creatGraph(Integer[][] matrix) {
        Graph graph = new Graph();

        for (int i = 0; i < matrix.length; i++) {//遍历每组数据
            Integer weight = matrix[i][0];
            Integer from = matrix[i][1];
            Integer to = matrix[i][2];

            if (!graph.nodes.containsKey(from)) {//没有from节点
                graph.nodes.put(from, new Node(from));//创建from节点,加入到图的点集之中
            }

            if (!graph.nodes.containsKey(to)) {//没有to节点
                graph.nodes.put(to, new Node(to));//创建to节点,加入到图的点集之中
            }

            Node fromNode = graph.nodes.get(from);
            Node toNode = graph.nodes.get(to);
            fromNode.nexts.add(toNode);//加入到from的nexts集合中
            fromNode.out++;//fromNode出度++
            toNode.in++;//toNode入度++

            Edge edge = new Edge(weight, fromNode, toNode);//创建边
            graph.edges.add(edge);//加入到图的边集
            fromNode.edges.add(edge);//加入到fromNode点的边集中
        }

        return graph;
    }
}

图的遍历的注意点:二叉树无环、图有环(避免图的环导致代码死循环) 

 

宽度遍历:一层一层向下遍历,先遍历距离A最近的点,再遍历距离A隔了一层的节点

深度遍历:一条路走到死,再返回去看还有哪条路可以走

图的宽度遍历

如果确定节点的类型为数字,可以将哈希表写成数组结构用索引查找,可以节省时间

package graph;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

public class Traversal {

    public static void widthTraversal(Node node) {
        if (node == null) {
            return;
        }
        HashSet<Node> hashSet = new HashSet();//放一个set防止重复把节点丢到队列里造成死循环
        Queue<Node> queue = new LinkedList();
        hashSet.add(node);
        queue.add(node);

        while (!queue.isEmpty()) {
            Node node0 = queue.poll();//从队列中弹出
            System.out.println(node0.value);//打印or执行操作

            for (Node node1 : node.nexts) {//遍历node的nexts的点集中的所有的点
                if(!hashSet.contains(node1)){//判断是否在set里面,是否出现过,防止环形结构死循环
                    hashSet.add(node1);//如果没有,就放入set和队列中
                    queue.add(node1);
                }
            }

        }
    }

}

 

图的深度遍历

 

    public static void deepTraversal(Node node) {
        if (node == null) {
            return;
        }
        HashSet<Node> hashSet = new HashSet();//放一个set防止重复把节点丢到队列里造成死循环
        Stack<Node> stack = new Stack();
        hashSet.add(node);
        stack.add(node);
        System.out.println(node.value);

        while (!stack.isEmpty()) {
            Node node0 = stack.pop();
            for (Node node1 : node0.nexts) {
                if(!node0.nexts.contains(node1)){
                    stack.push(node0);//node再重新入栈
                    stack.push(node1);//邻居入栈
                    hashSet.add(node1);//入set集合
                    System.out.println(node1.value);
                    break;
                }
            }
        }
    }

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

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

相关文章

VMware网络设置 桥接模式 NAT VMNET0 1 8

1.桥接模式 虚拟机与主机并列 可拥有独立IP 主机与虚拟机之间&#xff0c;以及各虚拟机之间都可以互访。对应虚拟机就被当成主机所在以太网上的一个独立物理机来看待&#xff0c;各虚拟机通过默认的 VMnet0 网卡与主机以太网连接&#xff0c;虚拟机间的虚拟网络为 VMnet0。这…

基于JAVA+SSM的房屋租赁系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会的发展和人们…

Fourier分析导论——第4章——Fourier级数的一些应用(E.M. Stein R. Shakarchi)

第 4 章 傅里叶级数的一些应用 Fourier series and analogous expansions intervene very naturally in the general theory of curves and surfaces. In effect, this theory, conceived from the point of view of analysis, deals obviously with the study of arbitra…

clickhouse安装与远程访问

安装&#xff08;本文以ubuntu系统为例&#xff09; 单节点设置​ 为了延迟演示分布式环境的复杂性&#xff0c;我们将首先在单个服务器或虚拟机上部署ClickHouse。ClickHouse通常是从deb或rpm包安装&#xff0c;但对于不支持它们的操作系统也有其他方法。 例如&#xff0c;…

在现在大环境下如何回到月薪过万的软件测试工程师?

测试工程师这个岗位对于有些人来说&#xff0c;可能月薪过万很容易&#xff0c;可对于有些人来说&#xff0c;仿佛已经达到瓶颈&#xff0c;任凭工作再卖力每月也只是四五千的薪资&#xff0c;月入过万对于这些人来说就是可望不可即&#xff0c;那么这些人怎么才能冲破瓶颈&…

SpringMvc执行流程(含过滤器Filter+拦截器interceptor)

目录 1.Mvc的概念 2.SpringMvc的概念 3.SpringMvc的核心组件 4.SpringMvc的执行流程 5.SpringMvcFilterInterceptor执行流程 一、Mvc的概念 Mvc(Model View Controller)&#xff1a;Mvc是一种设计规范&#xff0c;它将数据、视图、业务逻辑代码进行分离&#xff0c;降低代码…

DockerFile常用保留字指令及知识点合集

目录 DockerFile加深理解&#xff1a; DockerFile常用保留字指令 保留字&#xff1a; RUN&#xff1a;容器构建时需要运行的命令 COPY&#xff1a;类似ADD&#xff0c;拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 …

安卓系统手机便签app使用哪一款?

在现代快节奏的生活中&#xff0c;我们经常会遇到各种繁忙的事务和容易遗忘的备忘事项。为避免大家遗忘重要的事情&#xff0c;大家可以在常用的手机上安装记录备忘事项的工具&#xff0c;为了帮助安卓用户高效地记录和管理这些信息&#xff0c;今天我将向大家推荐一款功能强大…

文心一言 VS 讯飞星火 VS chatgpt (129)-- 算法导论11.1 4题

四、用go语言&#xff0c;我们希望在一个非常大的数组上&#xff0c;通过利用直接寻址的方式来实现一个字典。开始时该数组中可能包含一些无用信息&#xff0c;但要对整个数组进行初始化是不太实际的&#xff0c;因为该数组的规模太大。请给出在大数组上实现直接寻址字典的方案…

网页JS自动化脚本(十)新旧字符串关键词检测

关于两串字符串的对比有时候也是比较常用的, 因为我们的程序往往是需要将字符串转发,但往往会有一些添加或者减少,或者是其它的一些操作,所以我们在使用自动化脚本的时候可以使用字符串的对比功能来帮助我们减少工作出现的错误现在我举个例子,先在桌面上新建一个html文件然后打…

软件测试/测试开发丨如何利用ChatGPT自动生成测试用例思维导图

点此获取更多相关资料 简介 思维导图是一种用图形方式表示思维和概念之间关系的工具&#xff1a; 有些公司会使用思维导图编写测试用例&#xff0c;这样做的优点是&#xff1a; 1.可视化和结构化。 2.易于理解&#xff0c;提高效率。 而 ChatGPT 是无法直接生成 xmind 格式…

记一次对某变异webshell的分析

0x01 前言 在某活动中捕获到一个变异的webshell&#xff08;jsp文件格式&#xff09;&#xff0c;如图1.1所示。样本webshell的大致功能是通过加载字节码来执行恶意代码&#xff0c;整个webshell的核心部分逻辑是在字节码中。 样本文件下载链接&#xff1a; https://github.co…

java高并发系列-第1天:必须知道的几个概念

同步&#xff08;Synchronous&#xff09;和异步&#xff08;Asynchronous&#xff09; 同步和异步通常来形容一次方法调用&#xff0c;同步方法调用一旦开始&#xff0c;调用者必须等到方法调用返回后&#xff0c;才能继续后续的行为。异步方法调用更像一个消息传递&#xff…

下班后赚钱的8个副业,适合上班族

每个人都有不同的经济压力&#xff0c;尤其对于上班族来说&#xff0c;薪水或许不足以满足生活的各种需求和零花钱。因此&#xff0c;越来越多的人开始寻找机会在下班后赚取额外的收入。 如今有许多适合上班族的副业选择&#xff0c;帮助他们实现财务上的增长。不仅可以满足日常…

在Docker中设置Redis的密码

目录 1&#xff0c;介绍2&#xff0c;实现“Docker Redis设置密码”的整体流程3&#xff0c;具体实现步骤4&#xff0c;结论 1&#xff0c;介绍 Docker是一个开源的应用容器引擎&#xff0c;可以自动化部署、扩展应用程序。它可以帮助开发人员将应用程序及其依赖项打包到一个可…

中国社科院大学-新加坡新跃社科大学全球战略领导力博士学位教育项目招生简章

Singapore University of Social Sciences--University of Chinese Academy of Social Sciences Doctoral program on Global Strategic Leadership V13146152701 一、项目简介 全球经济正在经历由科技进步和创新、政治和人口剧烈变化所带来的巨大的不确定性和挑战。面对日…

Java中各个版本JDK分别有哪些常见的垃圾回收算法?它们的适用场景和开启方法是什么?

Java中各个版本JDK分别有哪些常见的垃圾回收算法&#xff1f;它们的使用场景和开启方法是什么&#xff1f; 1.1 JDK 1.8 中的垃圾回收算法1.2 JDK 11 中的垃圾回收算法1.3 JDK17中的垃圾回收算法 1.1 JDK 1.8 中的垃圾回收算法 Java 8引入了一些不同类型的垃圾回收算法&#x…

Vue中切换tab路由,提示this.$confirm确定和取消执行不同的逻辑

beforeRouteLeave (to, from, next) { // 离开页面 if (this.editFlag true) { this.$confirm(页面尚未保存&#xff0c;确认离开吗?, 提示, { distinguishCancelAndClose: true, // 区分取消和关闭 confirmButtonText: 确定, cancelButtonText: 取消, type: info }).then(()…

一文读懂RASP运行时防护平台及应用实践

「云原生安全既是一种全新安全理念&#xff0c;也是实现云战略的前提。 基于蚂蚁集团内部多年实践&#xff0c;云原生PaaS平台SOFAStack发布完整的软件供应链安全产品及解决方案&#xff0c;包括静态代码扫描Pinpoint&#xff0c;软件成分分析SCA&#xff0c;交互式安全测试IAS…

Git 安全警告修复手册:解决 `fatal: detected dubious ownership in repository at ` 问题 ️

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…