当前位置: 首页 > news >正文

「图::存储」链式邻接表|链式前向星(C++)

前置知识

上一节我们介绍了三种基本的存图结构:

「图」邻接矩阵|边集数组|邻接表(C++)

概述

他们各有优劣,为了综合他们的性能,

这一节我们来介绍两种以这三种结构为基础实现的高级存储结构:链式邻接表|链式前向星。

1.链式邻接表

结构

链式邻接表由一个二维表头数组head和一个边集数组e构成,

 *注意*:edges边集数组的结构详见:「图」邻接矩阵|边集数组|邻接表(C++)

表头数组head的功能类似邻接表,但它储存的并不是出边结构而是出边的编号。

一维head数组存储某个点的一系列出边编号,他们构成的二维head数组储存所有点的出边编号。

边集数组e以编号作为索引提供出边的全部信息{u,v,w}

将这两个数据结构封装成一个整体,称为chained_adjacency_list:

struct chained_adjacency_list {edges e;vector<vector<int>>head;
};

对于head[u][i]=idx;表示从u节点出发的第i条边在所有边中编号为idx

对于edges[idx]={u,v,w};编号为idx的边从u节点出发抵达v节点,边权为w

(边的序号通常时建图时读入数据时编排的。)

形象理解:

边集数组作为数据库存储全部边信息,

点集数组head悬挂了一排出边数组head[i],head[i]是第i个点的所有出边,每个head[i][j]存储第i个点的某一出边j的索引,用于对边集数组进行访问。

复杂度

空间复杂度: O(n+m)

n:节点数量

m:边数量

特点:

1.能用于各种图。

2.支持按节点访问。

3.能存储两点之间的多条边。

4.能存储边的编号。

5.先存入的先访问。

实际上链式邻接表综合了邻接表和边集数组的优点,它对邻接表的功能做了分离,使得邻接表不再存储出边的信息,而是存储边集数组的编号,以此作为索引对存储了出边信息的边集数组进行访问。

Code

struct chained_adjacency_list {edges e;vector<vector<int>>head;
};
void add(chained_adjacency_list& l) {int n; cin >> n;while (n--) {int u, v, w; cin >> u >> v >> w;l.e.push_back({ u,v,w });if(u>=l.head.size())l.head.resize(u+1);l.head[u].push_back(l.e.size() - 1);}
}
void get(const chained_adjacency_list& l) {for (const vector<int>& i : l.head)for(const int&idx:i)cout << "       " << l.e[idx].w << endl << l.e[idx].u << "------------->" << l.e[idx].v << endl;
}

2.链式前向星

结构

链式邻接表由一个一维表头数组head和一个边集数组e构成,

表头数组head只存储一个点的一个出边编号。

edge_with_next这个结构具有成员变量v,w,next;意为:这条边抵达v,边权为w,与其出发点相同的下一条边编号为next。你会发现它模拟了链表结构,即一个边单元存储着下一个边单元的next索引,依靠这个索引访问e中的下一条边。(这里的下一条是指出发点同为v的下一边)

边集数组e由edge_with_next构成数组,存储了全部出边信息。

将这两个数据结构封装成一个整体,称为chained_foward_star:

struct edge_with_next {int v;int w;int next;
};
using edges_with_next = vector<edge_with_next>;
struct chained_foward_star {edges_with_next e;vector<int>head;
};

对于head[u]=idx;表示从u节点出发的首条边在所有边中编号为idx

对于edges[idx]={v,w,next};编号为idx的边抵达v节点,边权为w,与其出发点相同的下一条边编号为next

(边的序号通常时建图时读入数据时编排的。)

形象理解:

边集数组作为数据库存储全部出边信息{v,w,next},

点集链表head悬挂一排链表,head[i]为一张链表的链表头,同时也是第i个点的首条出边,head[i].next储存i的下一条出边。


另外,在添加i点的新边时,链式前向星会将链表头head[i]更新为该边,同时该边的next会指向曾经的head[i],也就是说存边时会翻转先后顺序,即先存入的后访问。

复杂度

空间复杂度: O(n+m)

n:节点数量

m:边数量

特点:

1.能用于各种图。

2.支持按节点访问。

3.能存储两点之间的多条边。

4.能存储边的编号。

5.边能存储下一条边。(这里的下一条是指出发点同为v的下一边)

5.先存入的后访问。

实际上链式前向星的策略与链式邻接表有所不同,它的对一系列出边的悬挂并不是依靠出边数组实现,而是依靠类似链表的next指针结构相连的。

简单来说,链式邻接表依靠数组结构储存一个点的一系列出边;链式前向星依靠链表结构储存同一个点的一系列出边。

Code

struct edge_with_next {int v;int w;int next;
};
using edges_with_next = vector<edge_with_next>;
struct chained_foward_star {edges_with_next e;vector<int>head;
};
void add(chained_foward_star& star) {int n; cin >> n;while (n--) {int u, v, w; cin >> u >> v >> w;if (u >= star.head.size())star.head.resize(u + 1, -1);star.e.push_back({ v,w,star.head[u] });star.head[u] = star.e.size() - 1;}
}
void get(const chained_foward_star& star) {for (int i = 1; i < star.head.size();i++) {int idx = star.head[i];while (idx != -1) {cout << "       " << star.e[idx].w << endl << i << "------------->" << star.e[idx].v << endl;idx = star.e[idx].next;}}
}

测试Code

/*
11
1 2 20
2 1 30
2 0 30
4 3 100
8 9 60
9 7 40
3 6 50
5 6 20
7 8 15
2 4 30
1 3 5
以上为测试用例
*/
int main() {int test; cin >> test;switch (test) {case 4: {chained_adjacency_list cl;cout << "------------input------------" << endl;add(cl);cout << "------------output-----------" << endl;get(cl);break;}case 5: {chained_foward_star star;cout << "------------input------------" << endl;add(star);cout << "------------output-----------" << endl;get(star);break;}}return 0;
}

总结

相关文章:

「图::存储」链式邻接表|链式前向星(C++)

前置知识 上一节我们介绍了三种基本的存图结构&#xff1a; 「图」邻接矩阵|边集数组|邻接表&#xff08;C&#xff09; 概述 他们各有优劣&#xff0c;为了综合他们的性能&#xff0c; 这一节我们来介绍两种以这三种结构为基础实现的高级存储结构&#xff1a;链式邻接表|…...

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 10数据中心中的BGP

本章解答以下问题&#xff1a; ASN&#xff0c;团体&#xff08;community&#xff09;&#xff0c;属性&#xff08;attribute&#xff09;&#xff0c;最佳路径这些BGP术语是什么疑似&#xff1f;在数据中心中应该使用eBGP还是iBGP?在数据中心使用BGP时&#xff0c;应采用什…...

unity游戏开发——标记物体 一目了然

Unity游戏开发:标记物体,让开发变得一目了然 “好读书&#xff0c;不求甚解&#xff1b;每有会意&#xff0c;便欣然忘食。” 本文目录&#xff1a; Unity游戏开发 Unity游戏开发:标记物体,让开发变得一目了然前言1. 什么是Tag&#xff1f;2. Unity中如何添加和管理Tag步骤1&am…...

vue 项目打包图片没有打包进去问题解决

解决方法1.在导入图片的文件中通过 import 引入图片 这种方法只适合图片少的情况 <template> <img :srctestImg/> </template> <script> import testImg from /assets/img/testImg.png </script>2.封装公共方法,通过 new URL() 的方式…...

TCP的传输速度

如何确定TCP最大传输速度&#xff1f; TCP 的传输速度&#xff0c;受限于发送窗⼝&#xff0c;接收窗⼝以及⽹络设备传输能⼒。 其中&#xff0c;窗⼝⼤⼩由内核缓冲区⼤⼩决定。如果缓冲区与⽹络传输能⼒匹配&#xff0c;那么缓冲区的利⽤率就达到了最⼤化。 如何计算网络传…...

直播间的“骆驼”比沙漠还多?刀郎演唱会惊现“骆驼”

“送战友&#xff0c;踏征程&#xff0c;默默无语两行泪&#xff0c;耳边响起驼铃声……”8月30日&#xff0c;刀郎知交线上演唱会在微信视频号直播。一曲《驼铃》&#xff0c;勾起了无数人的回忆&#xff0c;离别的伤感、人性的关怀与温暖&#xff0c;通过悠然的旋律流入千万听…...

Android Studio gradle下载太慢了!怎么办?(已解决)

Android Studio&#xff01;你到底干了什么&#xff1f;&#xff01; 不能高速下载gradle&#xff0c;我等如何进行app编程&#xff1f;&#xff01; 很简单&#xff0c;我修改gradle地址不就是了。 找到gradle-wrapper.properties文件 修改其中distributionUrl的地址。 将 ht…...

安卓版Infuse来了 打造自己的影视墙

如何让安卓设备上的视频播放更高效&#xff1f;AfuseKt 或许能给出答案 AfuseKt 是一款功能强大的安卓网络视频播放器&#xff0c;专为满足用户对多样化媒体播放需求而设计。它不仅支持多种流行的在线存储和媒体管理平台&#xff0c;如阿里云盘、Alist、WebDAV 和 Emby 等&…...

【Python时序预测系列】高创新模型:基于xlstm模型实现单变量时间序列预测(案例+源码)

这是我的第351篇原创文章。 一、引言 LSTM在1990年代被提出&#xff0c;用以解决循环神经网络&#xff08;RNN&#xff09;的梯度消失问题。LSTM在多种领域取得了成功&#xff0c;但随着Transformer技术的出现&#xff0c;其地位受到了挑战。如果将LSTM扩展到数十亿参数&#…...

Ubuntu 22.04 系统中 ROS2安装

Ubuntu 22.04 系统中 ROS2安装 ROS2安装 # 多窗口终端工具 sudo apt update sudo apt install tilix打开软件&#xff0c;点击右上角图标进入设置 -> General -> size120, columns:48Command -> 勾选第一个 Run command as login shellColor -> Theme Color 选择…...

Vue内置指令v-once、v-memo和v-pre提升性能?

前言 Vue的内置指令估计大家都用过不少&#xff0c;例如v-for、v-if之类的就是最常用的内置指令&#xff0c;但今天给大家介绍几个平时用的比较少的内置指令。毕竟这几个Vue内置指令可用可不用&#xff0c;不用的时候系统正常跑&#xff0c;但在对的地方用了却能提升系统性能&…...

OpenHarmony轻松玩转GIF数据渲染

OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;提供了Image组件支持GIF动图的播放&#xff0c;但是缺乏扩展能力&#xff0c;不支持播放控制等。今天介绍一款三方库——ohos-gif-drawable三方组件&#xff0c;带大家一起玩转GIF的数据渲染&#xff0c;搞…...

torch.clip函数介绍

PyTorch 中,torch.clip函数用于对张量中的元素进行裁剪,将其值限制在指定的范围内。 一、函数语法及参数解释 torch.clip(input, min=None, max=None, out=None) input:输入张量,即要进行裁剪的张量。min(可选):裁剪的下限。如果未指定,则不进行下限裁剪。max(可选)…...

西北工业大学oj题-兔子生崽

题目描述&#xff1a; 兔子生崽问题。假设一对小兔的成熟期是一个月&#xff0c;即一个月可长成成兔&#xff0c;每对成兔每个月可以生一对小兔&#xff0c;一对新生的小兔从第二个月起就开始生兔子&#xff0c;试问从一对兔子开始繁殖&#xff0c;一年以后可有多少对兔子&…...

【Go语言成长之路】 模糊测试

文章目录 模糊测试一、前提二、创建项目三、添加待测试代码四、添加单元测试五、添加模糊测试 模糊测试 ​ 本教程介绍了 Go 中模糊测试的基础知识。通过模糊测试&#xff0c;随机数据会针对您的测试运行&#xff0c;以尝试找到漏洞或导致崩溃的输入。可以通过模糊测试发现的漏…...

异或运算的高级应用和Briankernighan算法

本篇文章主要回顾一下计算机的位运算&#xff0c;处理一些位运算的巧妙操作。 特别提醒&#xff1a;实现位运算要注意溢出和符号扩展等问题。 先看一个好玩的问题&#xff1a; $Problem1 $ 黑白球概率问题 袋子里一共a个白球&#xff0c;b个黑球&#xff0c;每次从袋子里拿…...

音视频入门基础:WAV专题(9)——FFmpeg源码中计算WAV音频文件每个packet的duration和duration_time的实现

一、引言 从文章《音视频入门基础&#xff1a;WAV专题&#xff08;6&#xff09;——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道&#xff0c;通过FFprobe命令可以显示WAV音频文件每个packet&#xff08;也称为数据包或多媒体包&#xff09;的信息&#xff0…...

AI写的论文查重率高吗?分享6款实测AI论文生成免费网站

在当今学术研究和论文写作领域&#xff0c;AI技术的迅猛发展为研究人员提供了极大的便利。特别是AI论文自动生成助手&#xff0c;它们不仅能够提高写作效率&#xff0c;还能帮助生成高质量的论文内容。以下是六款经过实测且免费的AI论文生成网站推荐&#xff1a; 一、千笔-AIP…...

【专题】2024年8月中国企业跨境、出海、国际化、全球化行业报告汇总PDF合集分享(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p37584 在全球化浪潮汹涌澎湃的当下&#xff0c;中国企业积极探索海外市场&#xff0c;开启了出海跨境的新征程。本报告合集旨在全面梳理出海跨境全球化行业的发展态势&#xff0c;涵盖多个领域的深度洞察。 从游戏、快消品、医疗器…...

[算法]单调栈解法

目录 739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 通常是一维数…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...