【数据结构】邻接表

一、概念

邻接表是一个顺序存储与链式存储相结合的数据结构,用于描述一个图中所有节点之间的关系。

若是一个稠密图,我们可以选择使用邻接矩阵;但当图较稀疏时,邻接矩阵就显得比较浪费空间了,此时我们就可以换成邻接表。

邻接表的逻辑结构有些类似于哈希桶,都是由数组与链表相结合的结构。一维数组存储结构体元素,结构体中需要包含每个节点的编号以及一个指针域,指针指向后续的所有邻接点

下面是邻接表的逻辑结构示意图(无向图):

可以看到,我们只需要顺着每个链表,就可以找到图中所有的边。但是对于无向图而言,还是存在一定的数据冗余情况,每条边都被记录了两次

因为邻接表的数组存放了所有的节点,我们又可以将其称为顶点数组。邻接表的实现方式有很多种,只要能够描述出所有节点与这些节点对应的所有边就是一个邻接表

二、数组实现邻接表

在做题的时候,为了效率,我们常常采用数组来模拟邻接表。但是数组实现邻接表的方式也五花八门,这里以y总同款邻接表和有向图为例

int e[N], ne[N], h[N], idx;void add(int a, int b) // 将a指向b的边加入邻接表
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

起初我看到这种实现邻接表的方式完全摸不着头脑,在一番研究后大致理解了其原理,希望能够对大家有所帮助

首先我们大致了解一下这段代码中不同的数组和变量代表了什么:

  • a:出发点
  • b:边指向的节点 
  • h:下标为节点编号,其中的元素存放对应节点的第一条出边编号,需要被初始化为-1
  • e:存放每条边指向的节点编号
  • ne:存放同一节点的下一条出边的编号
  • idx:边的编号

用数组模拟邻接表的大致思路是,将第i个节点的第一条出边编号放到h[i]中,通过h[i]能够取出其编号,用这个编号访问e[h[i]]就能够得到这条边指向的节点,此时我们就得到了一条完整的边;再用这个编号访问ne[h[i]]就能够得到同一节点的下一条出边编号。顺着这个逻辑我们就可以访问一个节点所有的出边

要使用数组实现的邻接表也很简单,我们只需要选择自己想要访问的节点i,然后得到节点i的第一条出边编号h[i],通过e[h[i]]得到这条出边指向的节点,接着通过ne[h[i]]得到节点i的下一条出边编号

不要忘了数组h一开始被初始化为-1,因此我们通过循环不断访问出边编号,直到当我们访问到-1时就说明节点i的所有出边已经全部访问完毕

因为所有的边都有自己的编号,我们是通过使用编号来访问这条边的尾和下一条边的,在数组模拟实现邻接表中边的编号非常重要!如果不能理解编号的作用就不能很好的理解数组模拟邻接表的原理。

如果看了上面还不是很理解,接下来是详细过程:

第一步,我们按顺序对所有的边进行编号

idx初始值为0,因此我们正好从0开始一个个将边存进邻接表

第0条边指向的节点,我们存进e[idx]中,并将h[a]即节点a的第一条出边编号赋值给ne[idx],然后将h[a]修改为第0条边的编号。此时第0条边变为节点a的第一条出边,最后idx++变成下一条边的编号

也就是说,节点i的第一条出边编号h[i]是一直在被更新的,每有一条新出边存入邻接表,对应节点的h[i]就会被更新为这条边的编号,而原来的h[i]就变为这条新出边的下一条出边编号,存进了ne[h[i]]中

最后idx++变为1,开始存下一条边

到这里相信大家已经明白如何将边存入邻接表了

以上面的例子为例,此时节点0的出边已经全部存入邻接表。我们通过访问h[0]就能得到节点0的第一条出边编号1,然后获取到其指向的节点e[h[0]]即节点2,通过ne[h[0]获取到其下一条出边编号0

最后编号会变为-1,此时说明该节点的所有出边已经遍历完毕

完.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE——认识异常

1.概念 在生活中,人有时会生病,在程序中也是一样,程序猿是一帮办事严谨、追求完美的高科技人才。在日常开发中,绞尽脑汁将代码写的尽善尽美,在程序运行过程中,难免会出现一些奇奇怪怪的问题。有时通过代码很…

【Unity】Unity中接入Admob聚合广告平台,可通过中介接入 AppLovin,Unity Ads,Meta等渠道的广告

一、下载Google Admob的SDK插件 到Google Admob官网中,切换到Unity平台 进来之后是这样,注意后面有Unity标识,然后点击下载,跳转到github中,下载最新的Admob插件sdk,导入到Unity中 二、阅读官方文档&…

【Linux】Screen的使用:新建、退出、再登陆

Linux screen 命令详解与使用指南 在Linux系统中,screen 是允许用户在单个终端会话中运行多个进程,并能在会话之间切换。 适用情况:screen 特别适用于远程登录(如通过SSH)时,确保即使网络连接断开&#x…

国产化ERP是什么?与SAP相比有何优势所在?

前段时间和一个工厂老板聊起来,他正为公司的 ERP 系统发愁呢。他们企业现在用的系统有点跟不上发展节奏了,在考虑换新的。但到底是继续选国际大牌 SAP 呢,还是试试国产化的 ERP 呢?这可真是个难题。这也不是他一家企业的困扰&…

如何通过钢筋计来优化施工安全

在现代建筑工程中,施工安全一直是首要关注的问题。特别是在高层建筑、桥梁和地下工程等复杂结构中,确保钢筋的正确安装和稳定性能,直接关系到工程的整体安全性和耐久性。钢筋计作为一种专门用于测量和监测钢筋应力和应变的设备,其…

使用node+prisma+socket+vue3实现一个群聊功能,拓展功能:使用lottie实现入场动画

使用nodeprisma和vue3实现一个群聊功能 后端代码编写 node环境初始化 新建一个空文件夹node,初始化node环境 npm init -y修改 packages.json,添加 type 为 module,删除 main {"name": "node","version": …

【C语言复习】分支和循环

【C语言复习】分支和循环 1. if语句1.1 if1.2 else1.3分支中包含多条语句1.4嵌套if1.5悬空else问题 2.关系操作符3. 条件操作符4.逻辑操作符:&& 、|| 、!4.1 逻辑取反运算符4.2 与运算符4.3或运算符4.4 练习:闰年的判断4.5短路 5.switch 语句5.1…

python爬虫 - 进阶正则表达式

🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、匹配中文 (一)匹配单个中文字符 (二…

Java项目实战II基于Java+Spring Boot+MySQL的服装销售平台(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在当今数字…

uniapp-小程序开发0-1笔记大全

uniapp官网: https://uniapp.dcloud.net.cn/tutorial/syntax-js.html uniapp插件市场: https://ext.dcloud.net.cn/ uviewui类库: https://www.uviewui.com/ 柱状、扇形、仪表盘库: https://www.ucharts.cn/v2/#/ CSS样式&…

硬件开发笔记(三十一):TPS54331电源设计(四):PCB布板12V转5V电路、12V转3.0V和12V转4V电路

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/142757509 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

ansible 流程控制

目录 1.流程控制 2.handlers触发器 2.1使用handlers案例 3.when 判断 3.1 案例1 用于给task设置条件 满足或者不满足运行对应模块 3.2 案例2 如果系统是centos则安装sl,cowsay 如果是unbantu则安装cmatrix 4.循环 4.1案例 1.流程控制 hand…

Git客户端使用之TortoiseGit和Git

git客户端有两个分别是TortoiseGit和Git Git用于命令行TortoiseGit用于图形界面。无论是Git还是TortoisGit都需要生成公/私钥与github/gitlab建立加密才能使用。 一、先介绍Git的安装与使用 1、下载与安装 安装Git-2.21.0-64-bit.exe(去官网下载最新版64位的),安…

SpringMVC2~~~

目录 数据格式化 基本数据类型可以和字符串自动转换 特殊数据类型和字符串间的转换 验证及国际化 自定义验证错误信息 细节 数据类型转换校验核心类DataBinder 工作机制 取消某个属性的绑定 中文乱码处理 处理json和HttpMessageConverter 处理Json-ResponseBody 处理…

Python精选200Tips:186-190

针对序列(时间、文本)数据的网络结构 续 P186-- 双向LSTM(Bidirectional Long Short-Term Memory 2005)(1)模型结构说明(2)创新性说明(3)示例代码:IMDB电影评论情感分析 …

通义灵码 Visual Studio 下载安装指南(附安装包)

文章目录 前言一、下载和安装指南方法 1:从插件市场安装方法 2:下载安装包安装方法 3:登录并开启智能编码之旅 二、使用指南总结 前言 通义灵码是基于通义大模型的智能编程辅助工具,它提供了多种强大的功能,旨在助力开…

【ProtoBuf】基础使用与编译

文章目录 ProtoBuf的使用基本使用指定proto3语法package声明符定义消息(message)定义消息字段字段唯一编号 编译序列化与反序列化序列化与反序列化使用 ProtoBuf的使用 流程如下: 编写 .proto文件,定义结构对象(message)及属性内容使用 protoc 编译器编…

[Halcon矩阵] 通过手眼标定矩阵计算相机旋转角度

📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉📢现…

GS-SLAM论文阅读笔记-MGSO

前言 MGSO首字母缩略词是直接稀疏里程计(DSO),我们建立的光度SLAM系统和高斯飞溅(GS)的混合。这应该是第一个前端用DSO的高斯SLAM,不知道这个系统的组合能不能打得过ORB-SLAM3,以及对DSO会做出怎么样的改进以适应高斯地图,接下来…

一次性语音芯片:重塑语音识别技术,引领智能化生活新时代

随着一次性语音芯片的突破性进展,语音识别技术正融入我们生活的方方面面,引领着智能化生活迈向一个全新的时代。这些芯片不仅体积小巧、成本低廉,更在性能上实现了质的飞跃,能够更精确地捕捉并理解人类语音。本文将解读关于一次性…