【数据结构】(四)图

news2025/2/4 10:45:23

目录

图的入门及无向图的实现

1. 图的相关概念

2. 图的相关术语

3. 图的存储结构

3.1 邻接矩阵

3.2 邻接表

3.3 邻接表实现

图的搜索算法

1. 深度优先搜索

1.1 搜索思路

1.2 代码实现

2. 广度优先搜索

2.1 搜索思路

2.2 代码实现

 

后记


数据结构分为逻辑结构和物理结构,从逻辑结构上,数据结构分为集合结构(数据元素之间没有关系)、线性结构(数据元素之间存在一对一的关系)、树形结构(数据元素之间存储一对多的关旭)和图形结构(数据元素之间存在多对多的关系);从物理结构上,数据结构分为顺序结构(把数据元素放到地址连续的存储单元里面)和链式结构(把数据元素存放在任意的存储单元里面,这组存储单元可以是连续的也可以是不连续的)。本文讲解数据结构中最后一种结构------图形结构。

图的入门及无向图的实现

1. 图的相关概念

  • 定义:图是由一组顶点和一组能够将两个顶点相连的边组成的

 

  • 特殊的图:
  1. 自环:即一条连接一个顶点和其自身的边;
  2. 平行边:连接同一对顶点的两条边;

 

  • 图的分类

按照连接两个顶点的边的不同,可以把图分为以下两种:

无向图:边仅仅连接两个顶点,没有其他含义;

有向图:边不仅连接两个顶点,并且具有方向;

2. 图的相关术语

相邻顶点:当两个顶点通过一条边相连时,我们称这两个顶点是相邻的,并且称这条边依附于这两个顶点。

度:某个顶点的度就是依附于该顶点的边的个数

子图:是一幅图的所有边的子集(包含这些边依附的顶点)组成的图;

路径:是由边顺序连接的一系列的顶点组成

环:是一条至少含有一条边且终点和起点相同的路径

连通图:如果图中任意一个顶点都存在一条路径到达另外一个顶点,那么这幅图就称之为连通图。

连通子图:一个非连通图由若干连通的部分组成,每一个连通的部分都可以称为该图的连通子图

3. 图的存储结构

要表示一幅图,只需要表示清楚以下两部分内容即可:

  1. 图中所有的顶点;
  2. 所有连接顶点的边;

常见图的存储结构有两种:邻接矩阵和邻接表

3.1 邻接矩阵

1.使用一个V*V的二维数组int[V][V] adj,把索引的值看做是顶点;

2.如果顶点v和顶点w相连,我们只需要将adj[v][w]和adj[w][v]的值设置为1,否则设置为0即可。

很明显,邻接矩阵这种存储方式的空间复杂度是V^2的,如果我们处理的问题规模比较大的话,内存空间极有可能不够用。

3.2 邻接表

1.使用一个大小为V的数组 Queue[V] adj,把索引看做是顶点;

2.每个索引处adj[v]存储了一个队列,该队列中存储的是所有与该顶点相邻的其他顶点。

很明显,邻接表的空间并不是是线性级别的,所以后面我们一直采用邻接表这种存储形式来表示图。

3.3 邻接表实现

图的表示,只需要表示清楚图中顶点,及与依赖于该顶点的边即可。由邻接表的形式来表示图,可以由Queue[]数组的索引表示顶点,而每个数组的值,即队列表示依赖于顶点的边的另一个顶点。

// 无向图 数据结构(邻接表的思想进行实现)
public class Graph {
    private final int V;//记录顶点数量
    private int E;//记录边数量
    private Queue<Integer>[] adj; //每个顶点的邻接表

    public Graph(int v) {
        //初始化顶点数量
        V = v;
        //初始化边的数量
        E=0;
        //初始每个顶点的邻接表
        adj=new Queue[V];
        for (int i = 0; i < adj.length; i++) {
            adj[i]=new Queue<Integer>();
        }
    }
    //获取图中顶点的数量
    public int V()
    {
        return V;
    }
    //获取图中边的数量
    public int E()
    {
        return E;
    }
    //向图中添加一条边 v-w
    public void addEdge(int v,int w)
    {
        //1.将w添加到顶点v的邻接表中
        adj[v].enqueue(w);
        //2.将v添加到顶点w的邻接表中
        adj[w].enqueue(v);
        //3.边的个数+1
        E++;
    }
    //获取和顶点v相邻的所有顶点
    public Queue<Integer> adj(int v)
    {
        return adj[v];
    }
}

图的搜索算法

在很多情况下,我们需要遍历图,得到图的一些性质,例如,找出图中与指定的顶点相连的所有顶点,或者判定某个顶点与指定顶点是否相通,是非常常见的需求。本节讲解图的深度优先搜索和广度优先搜索两种搜索的思想以及代码实现。

1. 深度优先搜索

1.1 搜索思路

在搜索时如果遇到一个结点既有子结点,又有兄弟结点,那么先找子结点,再找兄弟结点。下图以结点6为例,说明什么是子结点,什么是兄弟结点。简单来说就是一条路走到底,直到这条路走不下去了,再到这条路的起点尝试走其它路。

下图是一个顶点的深度优先搜索顺序

1.2 代码实现

public class DepthFirstSearch {
    private boolean[] marked;//索引代表顶点,值表示当前顶点是否已经被搜索
    private int count;//记录有多少个顶点与s顶点相通

    //构造深度优先搜索对象,使用深度优先搜索找出G图中s顶点的所有相通顶点
    public DepthFirstSearch(Graph G,int s)
    {
        //1.初始化代表顶点是否被搜索过的marked数组
        marked=new boolean[G.V()];
        //2.初始化G图中多少个顶点与顶点s相通,初始情况下count为0
        count=0;
        //3.调用深度优先搜索方法,更新count的值和marked的值
        dfs(G,s);
    }
    //使用深度优先搜索找出G图中v顶点的所有相通顶点
    private void dfs(Graph G, int v)
    {
        //1.将当前顶点标记为已搜索
        marked[v]=true;
        //2.搜索当前顶点的邻接表,若邻接表中的顶点不为0,如果邻接表中的顶点未被搜索,则递归深度优先搜索该顶点
        for (Integer w : G.adj(v)) {
            if (!marked[w])
                dfs(G,w);
        }
        //3.每次深度优先搜索后,count+1
        count++;
    }
    //判断w顶点与s顶点是否相通
    public boolean marked(int w)
    {
        //如果相通,则一定被搜索过
        return marked[w];
    }
    //获取与顶点s相通的所有顶点的总数
    public int count()
    {
        return count;
    }

2. 广度优先搜索

2.1 搜索思路

如果遇到一个结点既有子结点,又有兄弟结点,那么先找兄弟结点,然后找子结点。简单来说就是先把所有可能的路都走一步看看。

下图是一个顶点的广度优先搜索顺序

2.2 代码实现

public class BreadthFirstSearch {
    private boolean[] marked;//标识顶点是否被搜索过
    private int count;//与顶点相通的所有顶点个数
    private Queue<Integer> waitSearch;//辅助队列,用来存储待搜索的顶点

    //构造广度优先搜索对象,使用广度优先搜索找出G图中s顶点的所有相邻顶点
    public BreadthFirstSearch(Graph G,int s)
    {
        this.marked=new boolean[G.V()];
        this.count=0;
        this.waitSearch=new Queue<Integer>();
        BFS(G,s);
    }

    //广度优先搜索图G中与顶点V相通的所有顶点
    public void BFS(Graph G,int V)
    {
        //1.将顶点V标记为已搜索
        marked[V]=true;
        //2.将顶点V入队
        waitSearch.enqueue(V);
        //3.通过循环,如果队列不为空,则从队列中弹出一个待搜索的顶点,然后递归调用待搜索顶点邻接表中的所有顶点
        while (!waitSearch.isempty())
        {
            Integer wait = waitSearch.dequeue();
            for (Integer w : G.adj(wait)) {
                if(!marked(w))
                    BFS(G,w);
            }
        }

        //4.每次搜素都会找到一个相通的顶点,因此将相通的顶点+1
        count++;
    }

    //获取图G中与顶点V相通的所有顶点的个数
    public int count()
    {
        return count;
    }

    //判断w顶点与s顶点是否相通
    public boolean marked(int w)
    {
        return marked[w];
    }
}

有没有发现,广度优先搜索其实和树的层序遍历思路一样,而且实现都需要一个辅助队列。

 

后记

之所以在每日算法题中间穿插树和图这两篇数据结构,是因为后面我们将做和图相关的题目,因此要有一个基本了解,好好琢磨这两篇文章,相信对你的递归理解,及对数据结构的深入理解都会有质的提升!

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

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

相关文章

vscode 如何修改c/c++格式化风格,大括号不换行

在Visual Studio Code&#xff08;VSCode&#xff09;中&#xff0c;若要修改C代码格式化的风格以实现大括号不换行&#xff0c;通常会借助于插件C/C扩展中的ClangFormat配置。以下是具体的步骤&#xff1a; 确保已安装了C/C扩展&#xff1a; 打开VSCode的扩展市场&#xff08;…

【飞书小技巧】——飞书文档转 markdown 详细教程

飞书文档转 markdown 详细教程 基于项目:https://github.com/Wsine/feishu2md 如何使用 在线版 访问 https://feishu2md.onrender.com/ 粘贴文档链接即可&#xff0c;文档链接可以通过 分享 > 开启链接分享 > 复制链接 获得。 点击下载之后,会提示 Please wait. It ma…

回归预测 | Matlab基于POA-LSSVM鹈鹕算法算法优化最小二乘支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于POA-LSSVM鹈鹕算法算法优化最小二乘支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于POA-LSSVM鹈鹕算法算法优化最小二乘支持向量机的数据多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于POA-LSSVM…

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测 目录 回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-LSTM【24年新算…

西圣Olite开放式耳机持续100+天霸榜:品质优势再掀数码狂潮

随着开放式耳机的市场竞争加剧&#xff0c;用户对耳机的音质和配置要求越来越高。而西圣开放式耳机的不断推陈出新&#xff0c;正是对客户需求的完美回应&#xff01;西圣开放式耳机&#xff0c;在现在鱼龙混杂的市场上&#xff0c;能够获得着卓越的研发成果并且还在不断的追求…

从源码角度透视QTcpServer:解构QTcpServer的底层原理与技术细节

深入了解QTcpServer的底层原理和技术细节 一、背景二、QTcpServer的基本原理2.1、TCP协议简介2.2、QTcpServer的概念 三、QTcpServer源码解析3.1、QTcpServer的构造函数3.2、调用listen函数启动tcpserver3.3、QSocketNotifier的实现 总结 一、背景 QTcpServer是Qt网络模块中的…

CSS3的新盒子,选择器等

新增的选择器&#xff1a; 属性选择器&#xff1a; 结构伪类选择选器&#xff1a; nth较为重要&#xff1a;但公式中的字母必须是n 区别&#xff1a; nth-child&#xff1a; 认为父类下的都是儿子&#xff0c;此时就需要有对应的需要&#xff0c;如下&#xff0c;此时即使排1&…

DataFunSummit:2023年数据科学在线峰会:核心内容与学习收获(附大会核心PPT下载)

随着大数据时代的来临&#xff0c;数据科学已经在全球范围内成为了一门炙手可热的前沿学科。 数据会说谎&#xff1f;如何正确的挖掘并使用数据&#xff1f;前沿的科学实验如何做&#xff1f;实验又是如何欺骗你的&#xff1f;数据中台如何发挥功效&#xff1f;用户增长有捷径…

win10重装Ubuntu22.04安装报错复盘

目录 一&#xff1a;补充启动盘制作 二&#xff1a;错误信息[0xC0030570] The file or directory is corrupted and unreadable. 三&#xff1a;ubuntu重装步骤&#xff1a; 四&#xff1a;磁盘冗余阵列 五&#xff1a;尝试将SCS11(2,0.0), 第1分区(sda)设备的一个vfat文…

仰暮计划|“从米票、肉票、糖果票到肥皂票、煤票、棉花票等,生活里头的方方面面都能用粮票买到”

口述人&#xff1a;牛翠英(女) 整理人&#xff1a;霍芝冉 口述人基本信息&#xff1a;现68岁&#xff0c;河南省安阳市北关区霍家村人&#xff0c;现居河南安阳市区。 奶奶一生辛劳&#xff0c;操持家务&#xff1b;亲眼见证了时代变迁&#xff0c;社会发展&#xff0c;…

【FPGA】高云FPGA之IP核的使用->PLL锁相环

FPGA开发流程 1、设计定义2、设计输入3、分析和综合4、功能仿真5、布局布线6、时序仿真7、IO分配以及配置文件&#xff08;bit流文件&#xff09;的生成8、配置&#xff08;烧录&#xff09;FPGA9、在线调试 1、设计定义 使用高云内置IP核实现多路不同时钟输出 输入时钟50M由晶…

2024年美赛C题:Momentum in Tennis思路解析

Problem C: Momentum in Tennis 网球运动中的动力 【扫描下方二维码加入群聊&#xff0c;了解更多思路~】 中文题目&#xff1a; 在2023年温布尔登男子单打决赛中&#xff0c;20岁的西班牙新星卡洛斯阿尔卡拉斯击败了36岁的诺瓦克德约科维奇。这是德约科维奇自2013年以来在温布…

大数据StarRocks(九):资源隔离实战

前言 自 2.2 版本起&#xff0c;StarRocks 支持资源组管理&#xff0c;集群可以通过设置资源组&#xff08;Resource Group&#xff09;的方式限制查询对资源的消耗&#xff0c;实现多租户之间的资源隔离与合理利用。在 2.3 版本中&#xff0c;StarRocks 支持限制大查询&#…

如何使用 Supabase Auth 在您的应用程序中设置身份验证

在本文中&#xff0c;您将学习基本的关键概念&#xff0c;这些概念将帮助您掌握身份验证和授权的工作原理。 您将首先了解什么是身份验证和授权&#xff0c;然后了解如何使用 Supabase auth 在应用程序中实现身份验证。 &#xff08;本文内容参考&#xff1a;java567.com&…

2020年CSP-J认证 CCF非专业级别软件能力认证第一轮真题--完善程序题

2020 CCF认证第一轮&#xff08;CSP-J&#xff09;真题 三、完善程序题 第一题 质因数分解 给出正整数n&#xff0c;请输出将n质因数分解的结果&#xff0c;结果从小 到大输出。 例如&#xff1a;输入n120程序应该输出2 2 2 3 5,表示1202 X 2 X 2 X 3 X 5输入保2≤n≤10^9提…

PostGIS空间数据库之空间数据融合实践

目录 前言 一、ST_Union()简介 1、方法说明 2、参数介绍 二、ST_Collect()简介 1、方法说明 2、参数介绍 3、两者区别 三、实际案例实践 1、不重叠融合 2、空间重叠融合 总结 前言 众所周知&#xff0c;熟悉GIS桌面软件的同学一定都知道&#xff0c;想要对空…

跟着pink老师前端入门教程-day13

品优购案例 一、品优购项目规划 1. 品优购项目整体介绍 项目名称&#xff1a;品优购 项目描述&#xff1a;品优购是一个电商网站&#xff0c;我们要完成 PC 端首页、列表页、注册页面的制作 2. 品优购项目学习目的 1. 电商类网站比较综合&#xff0c;里面需要大量的布…

【Linux C | I/O模型】Unix / Linux系统的5种IO模型 | 图文详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

oracle 19c上安装样例数据库

样例schema的分类 HR: Human Resources OE: Order Entry PM: Product Media IX: Information Exchange SH: Sales History BI: Business Intelligence 安装样例数据库 1&#xff1a;HR的安装&#xff0c;通过dbca时候 2&#xff1a;HR的安装&#xff0c;安装完数据库后&#…

面试经典 150 题 -- 矩阵 (总结)

总的链接 : 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 36 . 有效的数独 模拟 : 用数组模拟哈希表来判断对应的行&#xff0c;列和当前元素所在的3*3方格中是否重复出现&#xff0c;是的话&#xff0c;直接return false…