数据结构:图

news2025/1/23 17:47:18

文章目录

        • 内存中存储图数据结构
          • 邻接矩阵存储方法
            • 用邻接矩阵(Adjacency Matrix)来表示一个图的缺点:浪费空间
            • 优点
          • 邻接表存储方法(Adjacency List)
          • 广度优先算法Breadth-First-Search(BFS)
          • 深度优先搜索Depth-First-Search(DFS)

  • 顶点:图中的元素

  • 图中的一个顶点可以与任意其他顶点建立连接关系。我们把这种建立的关系叫做边(edge)。

  • 度:跟顶点相连接的边的条数

  • 有向图:边有方向的图(微博)

    • 顶点的入度,表示有多少条边指向这个顶点;入度就表示有多少粉丝
    • 顶点的出度,表示有多少条边是以这个顶点为起点指向其他顶点。出度就表示关注了多少人
  • 无向图:边没有方向的图(微信)

  • 带权图(weighted graph)

    在带权图中,每条边都有一个权重(weight),我们可以通过这个权重来表示 QQ 好友间的亲密度。

内存中存储图数据结构

邻接矩阵存储方法

邻接矩阵的底层依赖一个二维数组。对于无向图来说,如果顶点 i 与顶点 j 之间有边,我们就将 A[i][j]和 A[j][i]标记为 1;对于有向图来说,如果顶点 i 到顶点 j 之间,有一条箭头从顶点 i 指向顶点 j 的边,那我们就将 A[i][j]标记为 1。同理,如果有一条箭头从顶点 j 指向顶点 i 的边,我们就将 A[j][i]标记为 1。对于带权图,数组中就存储相应的权重。

邻接矩阵存储起来比较浪费空间,但是使用起来比较节省时间。空间换时间

请添加图片描述

用邻接矩阵(Adjacency Matrix)来表示一个图的缺点:浪费空间

对于无向图来说,如果 A[i][j]等于 1,那 A[j][i]也肯定等于 1。实际上,我们只需要存储一个就可以了。也就是说,无向图的二维数组中,如果我们将其用对角线划分为上下两部分,那我们只需要利用上面或者下面这样一半的空间就足够了,另外一半白白浪费掉了。

如果我们存储的是稀疏图(Sparse Matrix),也就是说,顶点很多,但每个顶点的边并不多,那邻接矩阵的存储方法就更加浪费空间了。比如微信有好几亿的用户,对应到图上就是好几亿的顶点。但是每个用户的好友并不会很多,一般也就三五百个而已。如果我们用邻接矩阵来存储,那绝大部分的存储空间都被浪费了。

优点

邻接矩阵的存储方式简单、直接,因为基于数组,所以在获取两个顶点的关系时,就非常高效。其次,用邻接矩阵存储图的另外一个好处是方便计算。这是因为,用邻接矩阵的方式存储图,可以将很多图的运算转换成矩阵之间的运算。

邻接表存储方法(Adjacency List)

每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点。另外我需要说明一下,图中画的是一个有向图的邻接表存储方式,每个顶点对应的链表里面,存储的是指向的顶点。对于无向图来说,也是类似的,不过,每个顶点的链表中存储的,是跟这个顶点有边相连的顶点。

邻接表存储起来比较节省空间,但是使用起来就比较耗时间。时间换空间

如果我们要确定,是否存在一条从顶点 2 到顶点 4 的边,那我们就要遍历顶点 2 对应的那条链表,看链表中是否存在顶点 4。而且,我们前面也讲过,链表的存储方式对缓存不友好。所以,比起邻接矩阵的存储方式,在邻接表中查询两个顶点之间的关系就没那么高效了。

为了提高查找效率,可以将邻接表中的链表改成平衡二叉查找树(红黑树),或者其他动态数据结构,如跳表、散列表等。除此之外,我们还可以将链表改成有序动态数组,可以通过二分查找的方法来快速定位两个顶点之间否是存在边。

请添加图片描述

广度优先算法Breadth-First-Search(BFS)

直观地讲,它其实就是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后是次近的,依次往外搜索。

最坏情况下,终止顶点 t 离起始顶点 s 很远,需要遍历完整个图才能找到。这个时候,每个顶点都要进出一遍队列,每个边也都会被访问一次,所以,广度优先搜索的时间复杂度是 O(V+E),其中,V 表示顶点的个数,E 表示边的个数。当然,对于一个连通图来说,也就是说一个图中的所有顶点都是连通的,E 肯定要大于等于 V-1,所以,广度优先搜索的时间复杂度也可以简写为 O(E)

广度优先搜索的空间消耗主要在几个辅助变量 visited 数组、queue 队列、prev 数组上。这三个存储空间的大小都不会超过顶点的个数,所以空间复杂度是 O(V)

广度优先搜索,通俗的理解就是,地毯式层层推进,从起始顶点开始,依次往外遍历。广度优先搜索需要借助队列来实现,遍历得到的路径就是,起始顶点到终止顶点的最短路径

深度优先搜索Depth-First-Search(DFS)

最直观的例子就是“走迷宫”。假设你站在迷宫的某个岔路口,然后想找到出口。你随意选择一个岔路口来走,走着走着发现走不通的时候,你就回退到上一个岔路口,重新选择一条路继续走,直到最终找到出口。这种走法就是一种深度优先搜索策略。

图上的深度优先搜索算法的时间复杂度是 O(E),E 表示边的个数。

深度优先搜索算法的消耗内存主要是 visited、prev 数组和递归调用栈。visited、prev 数组的大小跟顶点的个数 V 成正比,递归调用栈的最大深度不会超过顶点的个数,所以总的空间复杂度就是 O(V)。

深度优先搜索用的是回溯思想,非常适合用递归实现。换种说法,深度优先搜索是借助来实现的。在执行效率方面,深度优先和广度优先搜索的时间复杂度都是 O(E),空间复杂度是 O(V)

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

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

相关文章

Android——GT库-日志工具

GT库在创造出来初期,里面的日志工具就一直存在的,经历了很久的迭代变更,当目前的最新版本,日志工具已经创造出更高级的调试日志方式了,接下来咋们来看看GT库中的日志工具具体使用方法吧。 使用GT库里的,当然…

web表单设计器的优点体现在哪?

在数字化管理越来越规范的当下,拥有一款优质高效的低代码开发平台,确实能给企业提质增效带来更大的帮助。很多客户朋友会问道:web表单设计器都有哪些特点?为什么能在企业的现代化办公管理中起到巨大的作用?今天&#x…

Linux终端远程工具xshell,xftp,mobasterm

目录 软件介绍 1.xshell 第一步: 第二步: 第三步: 第四步: 第5步: 2.xftp 第一步: 第二部: 第三步: 3.mobasterm 全能终端神器——MobaXterm 第一步: 第二步&a…

C1083无法打开包括文件: “atlbase.h”: No such file or directory

在打开别人的项目的过程中遇到了“atlbase.h”无法打开的问题,在此记录一下。1.下载ATL生成工具与缓解只下载ATL生成工具后面还会报错,直接下载下载ATL生成工具与缓解一步到位。下载的入口在:工具--->获取工具与功能。需要注意的是&#x…

Guitar Pro2023Win/Mac中文吉他/贝斯打谱识谱软件

Guitar Pro 是一款曲谱阅读器。以 GTP 结尾的曲谱文件都必须用 Guitar Pro 才能打开。Guitar Pro 凭借着其便利的制谱和读曲谱环境,在各大谱库论坛里都占据着一席之地,喜欢吉他的朋友一定略有耳闻。早几年该作者将它移植到了移动平台,现在你也…

7-2国王游戏

题目: 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。 首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。 然后,让这 n 位大臣排成一排,国王站在队伍的最前面。…

应用层——Web和HTTP

目录 1. HTTP概况 1.1 Web页面简介 1.2 URL-统一资源定位器 1.3 HTTP协议 2. HTTP连接的两种类型 2.1 HTTP非持久性连接(Non-persistent HTTP) 2.2 HTTP持久性连接(Persistent HTTP) 2.2.1 无流水(pipelining)的持久性连接 2.2.2 带有流水机制的持久性连接 3. HT…

一站式开发平台赋能办公全场景

近几年,数字化办公迎来了新的机遇,根据亿欧智库《2022中国数字化办公市场研究报告》推算,数字化办公2021年的市场规模达到973.89亿元,至2025年将达到1768.16亿元,整体增速保持平稳,2018-2025年的CAGR为15.8…

Mybatis 框架搭建封装JDBC,实现sql语句

目录 1、maven新建一个工程​编辑 2、添加POM.XML配置文件 3、创建实例包 4、创建一个环境资源根目录 5、配置环境文件 6、创建接口,添加方法 7、编写sql语句 8、创建测试类 8.1 、定义工厂模式 8.2 、定义会话 8.3、定义对象 8.5、获取Builder建造工厂 …

LAB3 EIGRP1实验

1 实验拓扑: 2 实验要求: 1>.R1-R3环回口0:192.168.100.x/32。 2>.R1上采用手动汇总的命令,汇总4条环回口成一条。 3>.R1上下发一条默认路由。 4>.实现R1到R2的环回口路由非等价负载。 5>.as 90都使用eigrp认证。 6>…

css动画效果之transition

transition-property规定设置过渡效果的 CSS 属性的名称。属性名属性值none没有属性会获得过渡效果。all所有属性都将获得过渡效果。property定义应用过渡效果的 CSS 属性名称列表,列表以逗号分隔。使用方式transition-property: width,background;/* 多个效果可用逗…

设计模式之装饰模式

1.前言 装饰模式:动态的给一个类添加一些额外职责,就增加功能来说,装饰模式比生成子类更加灵活。 装饰模式属于结构型模式,它是作为现有的 类的⼀个包装,允许向⼀个现有的对象添加新的功能, 同时⼜不改变其…

Spring创建和使用 (存储和读取) -- 1

Spring创建和使用 存储和读取 -- 1一、创建 Spring 项目1.1 创建⼀个 Maven 项目1.2 添加 Spring 框架支持1.3 添加启动类二、存储 Bean 对象2.1 创建 Bean2.2 将 Bean 注册到容器三、获取并使用 Bean 对象3.1 创建 Spring 上下文3.2 获取指定的 Bean 对象3.3 使用 Bean四、总结…

数据结构-第六期——并查集(Python)

目录 认识并查集 经典应用: 应用场景 并查集的操作 初始化 代码实现 合并 代码实现 查找 代码实现 查找代码【图解】 有多少个集(帮派)? 复杂度 查询的优化:路径压缩 【代码】用递归实现 并查集:初始化、查找、合并代码 蓝桥杯…

ES6之Promise

Promise是异步操作的一种解决方案 // 1.认识Promisedocument.addEventListener(click,()>{console.log(这里是异步的);});console.log(这里是同步的); Promise一般用来解决层层嵌套的回调函数&#xff08;回调地狱&#xff09;的问题 <!DOCTYPE html> <html lan…

JVM垃圾回收机制、JVM垃圾回收算法、JVM CMS与G1垃圾收集,JVM内存模型

C C 需要自己回收垃圾 重复回收&#xff1a; 回收掉别人的东西 忘记回收&#xff1a; 内存泄漏 Java虚拟机做自动化回收 垃圾回收器 Root Searching&#xff08;根可达&#xff09; GC Algorithms(垃圾回收算法) Mark-Sweep(标记清除) 缺点&#xff1a;碎片化&#xff0c;一…

Lua C接口编程(一)

引言 skynet 和 openresty 都是深度使用lua的典范&#xff0c;学习lua不经要学会基本语法&#xff0c;还要学会C语言与Lua交互。lua的一大优点就是能和c/c无缝连接&#xff0c;而且可以在不需要重复编译c/c的情况下可以修改lua文件并且起作用&#xff0c;当我们的项目文件很大…

【面试题】做了一份前端面试复习计划,保熟~

大厂面试题分享 面试题库前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库前言以前我看到面试贴就直接刷掉的&#xff0c;从不会多看一眼&#xff0c;直到去年 9 月份我开始准备面试时&#xff0c;才发现很多面试经验贴…

Kubernetes(k8s) 笔记总结(二)

提示&#xff1a;针对kubernetes的工作均衡学习。 文章目录1. Kubernetes 创建资源方式2. Kubernetes 操作NameSpace3. Kubernetes的 Pod应用3.1 Pod的 解释3.2 通过命令行来创建一个pod3.3 配置文件方式创建一个Pod3.4 dashboard 可视化操作Pod3.5 针对Pod的一些细节操作3.6 P…

如何评估PMO (项目管理办公室)的实施效果?

使用有效的组织战略、方法和技术&#xff0c;可以成功启动并制度化企业范围的PMO (项目管理办公室)。 一个企业范围内的PMO可以使用成熟的技术启动。 但你应该开发和使用适当的评估工具&#xff0c;以确定你的PMO实施的项目管理过程的有效性。这些工具可以包括正式的管理评估…