【数据结构】邻接表

news2024/10/13 2:12:43

一、概念

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

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

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

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

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

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

二、数组实现邻接表

在做题的时候,为了效率,我们常常采用数组来模拟邻接表。但是数组实现邻接表的方式也五花八门,这里以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.coloradmin.cn/o/2209336.html

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

相关文章

grpc的python使用

RPC 什么是 RPC ? RPC(Remote Procedure Call)远程过程调用,是一种计算机通信协议,允许一个程序(客户端)通过网络向另一个程序(服务器)请求服务,而无需了解…

JDK17常用新特性

目前国内大部分开发人员都是在使用jdk8,甚至是jdk6,但是随着jdk的更新迭代,jdk8我觉得可能就会慢慢的淡出舞台,随着目前主流框架最新版推出明确说明了不再支持jdk8,也促使我不得不抓紧学习了解一波jdk17的新特性&#…

手写mybatis之解析和使用ResultMap映射参数配置

前言 学习源码是在学习什么呢? 就是为了通过这些源码级复杂模型中,学习系统框架的架构思维、设计原则和设计模式。在这些源码学习手写的过程中,感受、吸收并也是锻炼一种思维习惯,并尝试把这些思路技术迁移到平常的复杂业务设计开…

MD5消息摘要算法学习

MD5(Message Digest Algorithm 5)是一种广泛使用的哈希函数,它用于生成128位的哈希值(也称为消息摘要)。MD5主要用于确保信息的完整性,即可以通过对数据生成的哈希值来验证数据是否被篡改。尽管MD5在过去被…

60. 排列序列【回溯】

文章目录 60. 排列序列解题思路Go代码 60. 排列序列 60. 排列序列 给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n 3 时, 所有排列如下: “123”“132”“213”“231”“31…

SpringBoot 集成GPT实战,超简单详细

Spring AI 介绍 在当前的AI应用开发中,像OpenAI这样的GPT服务提供商主要通过HTTP接口提供服务,这导致大部分Java开发者缺乏一种标准化的方式来接入这些强大的语言模型。Spring AI Alibaba应运而生,它作为Spring团队提供的一个解决方案&…

Spring Boot 3 文件管理:上传、下载、预览、查询与删除(全网最全面教程)

在现代Web应用中,文件管理是一个非常重要的功能。Spring Boot作为Java开发领域的热门框架,提供了丰富的工具和API来简化文件管理的操作。本文将详细介绍如何使用Spring Boot 3进行文件的上传、下载、预览、查询与删除操作,并提供一个完整的示…

OpenCV 环境配置

首先下载opencv,在opencv官网进行下载。 按照上面的步骤,点击进去 滑至底部,不切换至不同页,选择合适的版本进行下载(Window系统选择Windows版本进行下载)。 接下来以4.1.2版本为例: 点击之后会进入这个页面&#xff…

聚类分析 | NRBO-GMM聚类优化算法

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 (创新)NRBO-GMM聚类优化算法 (NRBO聚类优化,创新,独家) 牛顿-拉夫逊优化算法优化GMM高斯混合聚类优化算法 matlab语言,一键出图,直接运行 1.牛顿-拉夫逊优化算法(New…

STM32—BKP备份寄存器RTC实时时钟

1.BKP简介 BKP(Backup Registers)备份寄存器BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位TAMP…

教培机构如何向知识付费转型

在数字化时代,知识付费已成为一股不可忽视的潮流。面对这一趋势,教育培训机构必须积极应对,实现向知识付费的转型,以在新的市场环境中立足。 一、教培机构应明确自身的知识定位。 在知识付费领域,专业性和独特性是关键…

【Python】selenium获取鼠标在网页上的位置,并定位到网页位置模拟点击的方法

在使用Selenium写自动化爬虫时,遇到验证码是常事了。我在写爬取测试的时候,遇到了点击型的验证码,例如下图这种: 这种看似很简单,但是它居然卡爬虫?用简单的点触验证码的方法来做也没法实现 平常的点触的方…

数据迁移:如何保证在不停机的情况下平滑的迁移数据

1. 引言 数据迁移是一个常见的需求,比如以下的场景,我们都需要进行数据迁移。 大表修改表结构单表拆分进行分库分表、扩容系统重构,使用新的表结构来存储数据 2. 迁移准备 2.1 备份工具 2.1.1 mysqldump mysqldump 是 MySQL 自带的用于…

【计网】从零开始认识https协议 --- 保证安全的网络通信

在每个死胡同的尽头, 都有另一个维度的天空, 在无路可走时迫使你腾空而起, 那就是奇迹。 --- 廖一梅 --- 从零开始认识https协议 1 什么是https协议2 https通信方案2.1 只使用对称加密2.2 只使用非对称加密2.3 双方都使用非对称加密2.4 …

Winform和WPF的技术对比

WinForms(Windows Forms)和WPF(Windows Presentation Foundation)是用于创建桌面应用程序的两种技术。尽管两者都可以用于开发功能强大的Windows应用程序,但它们的设计理念、功能和开发体验都有显著区别。在本文中&…

(亲测可行)ubuntu下载安装c++版opencv4.7.0和4.5.0 安装opencv4.5.0报错及解决方法

文章目录 🌕系统配置🌕打开终端,退出anacoda激活环境(如果有的话)🌕安装依赖🌙安装g, cmake, make, wget, unzip,若已安装,此步跳过🌙安装opencv依赖的库🌙安装可选依赖 …

Smartfusion2开发环境的搭建

Libero软件安装包括libero安装、bibero补丁安装、bibero的license添加和官方ip库的添加等4部分内容组成。具体内容如下所示: 1 Libero软件安装 1、解压LiberoSoC_v11.8的安装包到当前目录,然后运行Libero中的可执行软件进行安装; 图1 双击l…

Javascript实现Punycode编码/解码

Punycode编码/解码的Javascript实现。 用法 const punycode require(punycode); console.log(punycode.encode(用法)); //nwwn1p console.log(punycode.decode(nwwn1p)) //用法console.log(punycode.toIDN(用法.中国)); //xn--nwwn1p.xn--fiqs8s console.log(punycode.fromI…

【AAOS】Android Automotive 13模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r69 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch sdk_car_x86_64-userdebug make -j8 运行效果 emualtor HomeMapAll appsSettings…

CUDA-X

NVIDIA CUDA-X 文章目录 前言一、CUDA-X 微服务CUDA-X 微服务CUDA-X 库二、CUDA-X 数据处理三、CUDA-X AI四、CUDA-X HPC总结前言 适用于 AI 的采用 GPU 加速的微服务和库。 释放 GPU 在 AI 应用程序中的潜能 探索 NVIDIA CUDA-X AI 正在推动变革的 AI 领域和可在其中使用的 G…