图的深度优先遍历和广度优先遍历

news2024/11/26 20:46:24

目录

图的创建和常用方法

深度优先遍历(Depth First Search)

广度优先遍历(Broad First Search) 


图的创建和常用方法

//无向图
public class Graph {
    //顶点集合
    private ArrayList<String> vertexList;
    //存储对应的邻接矩阵
    private int[][] edges;
    //边数
    private int numOfEdges;

    //构造方法
    //传入顶点数
    public Graph(int numOfVertex) {
        this.vertexList = new ArrayList<>(numOfVertex);
        this.edges = new int[numOfVertex][numOfVertex];
        this.numOfEdges = 0;//边数初始为0
    }
    //添加顶点
    public void  interVertex(String vertex){
        vertexList.add(vertex);
    }
    //添加边
    public void interEdge(int v1,int v2,int weight){
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfEdges++;
    }


//图中常用方法:
    //返回节点的个数
    public int getNumOfVertex(){
        return vertexList.size();
    }
    //得到边的数目
    public int getNumOfEdges(){
        return numOfEdges;
    }
    //返回节点i对应的数据,以添加的顺序为准
    public String getValueByIndex(int i){
        return vertexList.get(i);
    }
    //返回v1,v2的权值
    public int getWeight(int v1,int v2){
        return edges[v1][v2];
    }
    //显示图所对应的矩阵
    public void showGraph(){
        for(int[] link:edges){
            System.out.println(Arrays.toString(link));
        }
    }

    //测试
    public static void main(String[] args) {
        int n = 5;
        String[] vertexs={"A","B","C","D","E"};
        Graph graph = new Graph(n);
        //添加顶点
        for(String vertex:vertexs){
            graph.interVertex(vertex);
        }
        //添加边:A-C  A-B  A-E  B-D
        graph.interEdge(0,2,1);
        graph.interEdge(0,1,1);
        graph.interEdge(0,4,1);
        graph.interEdge(1,3,1);

        graph.showGraph();
    }
}

邻接矩阵: 

 

 

 

深度优先遍历(Depth First Search)

深度优先:每次访问当前节点后,首先访问当前节点的第一个邻接矩阵

添加标记顶点是否访问的数组:

 private boolean[] isVisted;

 在构造方法中初始化:

  this.isVisted = new boolean[numOfVertex];

得到第一个邻接节点的下标w: 

 //得到第一个邻接节点的下标w
    public int getFirstNeighbor(int index){
        for (int j = 0; j< vertexList.size(); j++) {
            if (edges[index][j]>0){
                return j;
            }
        }
        return -1;
    }

 根据前一个节点的坐标获取下一个邻接节点:

//根据前一个节点的坐标获取下一个邻接节点
    public int getNextNeighbor(int v1,int v2){
        for (int j = v2+1; j < vertexList.size(); j++) {
            if (edges[v1][j]>0)return j;
        }
        return -1;
    }

深度优先遍历: 

 //深度优先遍历
    private void dfs(boolean[] isVisted,int i){
        //首先访该节点,输出
        System.out.print(getValueByIndex(i)+"->");
        //访问标记
        isVisted[i] = true;
        //访问节点的第一个邻接节点
        int w = getFirstNeighbor(i);
        while (w!=-1){
            //有的话并且没有被访问过,就遍历该节点
            if (!isVisted[w]){
                dfs(isVisted,w);
            }
            //如果已经被访问过,就访问下一个
            w = getNextNeighbor(i,w);
        }
    }

 若是非连通图(有孤立点),需要将每个顶点深度遍历:

//若是非连通图,需要将每个顶点深度遍历
    public void dfs(){
        for (int i = 0; i < vertexList.size(); i++) {
            if (!isVisted[i]){
                dfs(isVisted,i);
            }
        }
    }

 如下图的深度遍历:

 

 //测试
    public static void main(String[] args) {
        int n = 6;
        String[] vertexs={"A","B","C","D","E","F"};
        Graph graph = new Graph(n);
        //添加顶点
        for(String vertex:vertexs){
            graph.interVertex(vertex);
        }
        //添加边:A-C  A-B  A-E  B-D
        graph.interEdge(0,2,1);
        graph.interEdge(0,1,1);
        graph.interEdge(0,4,1);
        graph.interEdge(1,3,1);

        graph.showGraph();

        graph.dfs();
    }

广度优先遍历(Broad First Search) 

 广度优先:先访问所有直接相邻的节点,然后访问所有与这些节点相邻的节点,以此类推,直到遍历完整个图。

//广度优先遍历
    //对一个节点进行广度优先算法
    private void bfs(boolean[] isVisted,int i){
        int u;//队列头结点的下标
        int w;//邻接节点
        LinkedList queue = new LinkedList();
    //  访问节点,输出
        System.out.print (getValueByIndex(i)+"=>");
    //    标记已访问
        isVisted[i]=true;
    //    添加到队列
        queue.addLast(i);
        while (!queue.isEmpty()){
            u = (Integer) queue.removeFirst();
            //得到第一个邻接节点的下标
            w = getFirstNeighbor(u);
            while (w!=-1){
                if (!isVisted[w]){
                    //没有访问过
                    System.out.print(getValueByIndex(w)+"=>");
                    isVisted[w] = true;
                    queue.addLast(w);
                }
                //以u为前一个节点,访问过去下一个节点
                w = getNextNeighbor(u, w);
            }
        }

    }
    //非连通图 广度优先遍历
    public void bfs(){
        this.isVisted = new boolean[vertexList.size()];
        for (int i = 0; i < vertexList.size(); i++) {
            if (!isVisted[i]){
                bfs(isVisted,i);
            }
        }
    }

测试:

System.out.println("广度优先");
graph.bfs();

 深度和广度测试:

public static void main(String[] args) {
        int n = 8;
        String[] vertexs={"1","2","3","4","5","6","7","8"};
        Graph graph = new Graph(n);
        //添加顶点
        for(String vertex:vertexs){
            graph.interVertex(vertex);
        }
        //添加边:1-2 1-3 2-4 2-5 4-8 5-8 3-6 3-7
        graph.interEdge(0,1,1);
        graph.interEdge(0,2,1);
        graph.interEdge(1,3,1);
        graph.interEdge(1,4,1);
        graph.interEdge(3,7,1);
        graph.interEdge(4,7,1);
        graph.interEdge(2,5,1);
        graph.interEdge(2,6,1);

        graph.showGraph();
        System.out.println("深度优先");
        graph.dfs();
        System.out.println();
        System.out.println("广度优先");
        graph.bfs();
    }

 

 

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

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

相关文章

Spring Security 详解

目录 一、Spring Security简介1.1 概述1.2 历史 二、Spring Security功能三、Spring Security支持的身份认证模式四、SpringBoot项目构建4.1 项目搭建4.2 内存认证4.3 UserDetailsService 处理逻辑4.4 数据库认证4.5 PasswordEncoder4.6 自定义登录页面4.7 会话管理4.8 认证成功…

添加SQLCipher 到项目中

文章目录 一、克隆下载SQLCipher二、手动导入1. 生成sqlite3.c2. 在项目中添加命令3. 添加 Security.framework 三、CocoaPods导入 SQLCipher官方地址 一、克隆下载SQLCipher $ cd ~/Documents/code $ git clone https://github.com/sqlcipher/sqlcipher.git二、手动导入 1.…

Qt5兼容使用之前Qt4接口 intersect接口

1. 问题 项目卡中遇到编译报错&#xff0c; 错误 C2039 “intersect”: 不是“QRect”的成员 。 2. 排查过程 排查到依赖的第三方代码&#xff0c;使用 intersect 接口&#xff0c; 跟踪排查到头文件中使用了***#if QT_DEPRECATED_SINCE(5, 0)*** #if QT_DEPRECATED_SINCE…

大学生创业运营校园跑腿小程序怎么样?

校园跑腿小程序是一种基于移动互联网的服务平台&#xff0c;旨在为大学生提供便捷的跑腿服务。它可以连接大学生用户和需要代办事务的人群&#xff0c;实现多方共赢的局面。接下来&#xff0c;我将从需求背景、市场前景、功能特点等方面进行分析。 首先&#xff0c;校园跑腿小程…

ETLCloud+MaxCompute实现云数据仓库的高效实时同步

MaxCompute介绍 MaxCompute是适用于数据分析场景的企业级SaaS&#xff08;Software as a Service&#xff09;模式云数据仓库&#xff0c;以Serverless架构提供快速、全托管的在线数据仓库服务&#xff0c;消除了传统数据平台在资源扩展性和弹性方面的限制&#xff0c;最小化用…

TransNetR:用于多中心分布外测试的息肉分割的基于transformer的残差网络

TransNetR Transformer-based Residual Network for Polyp Segmentation with Multi-Center Out-of-Distribution Testing 阅读笔记 1. 论文名称 《TransNetR Transformer-based Residual Network for Polyp Segmentation with Multi-Center Out-of-Distribution Testing》 用…

STM32基于CubeIDE和HAL库 基础入门学习笔记:物联网项目开发流程和思路

文章目录&#xff1a; 第一部分&#xff1a;项目开始前的计划与准备 1.项目策划和开发规范 1.1 项目要求文档 1.2 技术实现文档 1.3 开发规范 2.创建项目工程与日志 第二部分&#xff1a;调通硬件电路与驱动程序 第三部分&#xff1a;编写最基础的应用程序 第四部分&…

JAVA毕业设计093—基于Java+Springboot+Vue的招聘系统(源码+数据库)

基于JavaSpringbootVue的招聘系统(源码数据库)093 一、系统介绍 本系统前后端分离 本系统分为管理员、HR、用户三种角色 用户角色包含以下功能&#xff1a; 登录、注册、简历(搜索、投递和收藏)、hr联系、我的关注、我的收藏、我的简历、简历投递管理、面试管理、个人中心…

zabbix5.0安装教程(超详细)实测完美可用

5.0 版本对基础环境的要求有⼤的变化&#xff0c;最⼤的就是对 php 版本的要求&#xff0c;最低要求7.2.0 版本,对 php 扩展组件版本也有要求&#xff0c;详见官网文档 https://www.zabbix.com/documentation/current/manual/installation/requirements 准备好⼀台linux服务器&…

day23-113. 路径总和ii

113. 路径总和ii 力扣题目链接(opens new window) 给定一个二叉树和一个目标和&#xff0c;找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树&#xff0c;以及目标和 sum 22&#xff0c; 思路 利用…

【团队协作开发】IDEA中Git从远程其他分支拉取代码并同步更新到自己的分支中更新不全问题解决

出现这个问题往往是因为没有先拉取远程分支的最新变化到本地导致的&#xff0c;具体操作流程和解决方法如下&#xff1a; 1、首先&#xff0c;先确保本地有一个和远程要拉取分支(比如dev_z)相关联的分支&#xff0c;如果没有&#xff1a;选择远程要拉取的分支&#xff0c;点击C…

postman官网下载安装登录详细教程

目录 一、介绍 二、官网下载 三、安装 四、注册登录postman账号&#xff08;不注册也可以&#xff09; postman注册登录和不注册登录的使用区别 五、关于汉化的说明 一、介绍 简单来说&#xff1a;是一款前后端都用来测试接口的工具。 展开来说&#xff1a;Postman 是一个…

探讨C语言是否仍然满足现代编程需求

在过去的30年里&#xff0c;有人试图通过引入一门新的语言来取代C语言&#xff0c;其中一位被简称为BS的人也持有类似观点。尽管这门新语言在某些方面表现出色&#xff0c;但它并未能完全取代C语言&#xff0c;而是在特定领域发展出自己的优势。此后&#xff0c;又有一家公司决…

在线Word怎么转换成PDF?Word无法转换成PDF文档原因分析

不同的文件格式使用方法是不一样的&#xff0c;而且也需要使用不同的工具才可以打开编辑内容&#xff0c;针对不同的场合用户们难免会用到各种各样的文件格式&#xff0c;要想在不修改内容的前提下提高工作效率&#xff0c;那就需要用到文件格式转换&#xff0c;那么在线Word怎…

苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket

前言 HM新出springboot入门项目《苍穹外卖》&#xff0c;笔者打算写一个系列学习笔记&#xff0c;“苍穹外卖项目解读”&#xff0c;内容主要从HM课程&#xff0c;自己实践&#xff0c;以及踩坑填坑出发&#xff0c;以技术&#xff0c;经验为主&#xff0c;记录学习&#xff0…

爬虫018_urllib库_cookie反爬_post请求百度翻译获取百分翻译内容_以及详细翻译内容---python工作笔记037

然后我们来看如何用urllib发送post请求,这里我们 用百度翻译为例 我们翻译一个spider,然后我们看请求,可以看到有很多 找到sug这个 可以看到这里的form data,就是post请求体中的内容 然后我们点击preview其实就是 返回的实际内容 然后请求方式用的post 然后我们把上面的信息…

Untiy Json和Xml的序列化和反序列化

Json的序列化和反序列化 1.定义数据类 [Serializable] public class ZoomPoint {// 点名称, 将作为Key被字典存储public string name;// 轴心X坐标public Vector2 pivot Vector2.one / 2;// 放大倍率&#xff0c;小于1是为缩小倍率&#xff0c;小于0是取绝对值&#xff0c;不…

BIGEMAP双端buff助力AEC行业无压力进行AutoCAD作图

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP AEC行业&#xff0c;即建筑(Architecture)、工程(Engineering)、施工(Construction)&#xff0c;热衷于引入信息通信技术&#xff0c;不仅活跃于国际舞台&#xff0c;还…

GoFastDFS单节点部署

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

Oracle 开发篇+Java通过HiKariCP访问Oracle数据库

标签&#xff1a;HikariCP、数据库连接池、JDBC连接池、释义&#xff1a;HikariCP 是一个高性能的 JDBC 连接池组件&#xff0c;号称性能最好的后起之秀&#xff0c;是一个基于BoneCP做了不少的改进和优化的高性能JDBC连接池。 ★ Java代码 import java.sql.Connection; impor…