首页 > 其他分享 >图的存储

图的存储

时间:2023-04-19 23:14:16浏览次数:31  
标签:map 存储 下标 idx 顶点 节点 号边

所谓图(graph),是图论中基本的数学对象,包括一些顶点,和连接顶点的边。

图可以分为有向图和无向图,有向图中的边是有方向的,而无向图的边是双向连通的。

  • 邻接矩阵 (适用于稠密图)

用一个二维数组来记录各个点之间的关系,若u到v之间有一条边则可用map[u][v]=1来表示,具体如下

对应的无向图为

对于带权图 将1改成权值即可

邻接矩阵的优点显而易见:简单好写,查询速度快。但缺点也很明显:空间复杂度太高了。 n个点对应大小 n^2的数组,如果点的数量达到10000,这种方法就完全不可行了。

  • 邻接表

首先,我们用一个结构体vector存储每个边的起点和终点,然后用一个二维vector存储边的信息。

用map[a][b]=c 来表示顶点为a的第b条边是c号边

以下面为例:

8 9

1 2 //0号边

1 3 //1号边

1 4 //2号边

2 5 //3号边

2 6 //4号边

3 7 //5号边

4 7 //6号边

4 8 //7号边

7 8 //8号边

 

最终二维vector中存储的是如下信息

0 1 2 //1号顶点连着0、1、2号边

3 4  //2号顶点连着3、4号边

5   //3号顶点连着5号边

6 7 //4号顶点连着6、7号边

    //5号顶点没有边

   //6号顶点没有边

8  //7号顶点连着8号边

   //8号顶点没有边

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<vector>
 4 using namespace std;
 5 
 6 struct edge {
 7     int st, ed; 
 8 };
 9 vector <int> map[100001];  
10 vector <edge> vec;  
11 int main() {
12 
13     int n, m;
14     cin >> n >> m; 
15     for (int i = 0; i < m; i++) { 
16         int st, ed;
17         cin >> st >> ed;
18         vec.push_back({ st, ed }); //初始化存边的s数组  
19     }
20 
21     for (int i = 0; i < m; i++)
22         map[vec[i].st].push_back(i);
23     //初始化map数组,vec[i].st表示顶点,在该顶点加入其对应的边
24 
25     return 0;
26 }

如何去遍历呢?

x表示顶点

map[x].size()表示该顶点具有边的个数

map[x][i]表示x顶点的第i条边是哪一条边

vec[map[x][i]].ed 表示x顶点的第i条边的边的终点

以该图为例:

map[1][0]表示 0 号边 map[2][0]表示第3条边 map[4[1]表示第8条边

那么vec[map[1][0]].st就等于2号顶点

 1 void dfs(int x) {         
 2     cout << x<<" ";
 3 
 4     for (int i = 0; i < map[x].size(); i++)
 5     {
 6         int j = vec[map[x][i]].ed;  
 7         if (!st[j])
 8         {
 9             st[j] = 1;
10             dfs(j);
11         }
12     }
13 }

 

  • 链式前向星   (h数组初始化为-1)

idx是边的编号,a是边的起点,b是边的终点
e[idx] 存idx号边指向的点。
h[a] 存从a号点出发的某一条边的编号
ne[idx] 存idx号边(起点为a)的上一条边(也是以a为起点的)
i=ne[i]循环遍历所有从a出发的边

输出邻接表:

1:->4->7->2
2:->5->8->1
3:->9->4
4:->6->3->1
5:->2
6:->4
7:->1
8:->2
9:->3

对比原图

节点的编号是指上图所画的树中节点的值,范围是从1->n,编号用e[i]数组存储。

节点的下标指节点在数组中的位置索引,数组之间的关系就是通过下标来建立连接,下标用idx来记录。idx范围从0开始,如果idx==-1表示空。

e[i]的值是编号,是下标为i节点的编号。

ne[i]的值是下标,是下标为i的节点的next节点的下标。

h[i]存储的是下标,是编号为i的节点的next节点的下标,比如编号为1的节点的下一个节点是2,那么我输出e[h[1]]就是2。

 

链式前向星是一种常用的图存储方式,其主要优点如下:

1. 空间利用率高:链式前向星只需存储边信息,相对于邻接矩阵等其他图存储方式,可以大大节约空间。

2. 支持动态图:链式前向星在插入和删除边时具有较好的效率,支持实时更新图。

3. 方便遍历所有与某个点相邻的边:链式前向星通过一个数组来记录每个点最后一条边的位置,逐个遍历这些边即可找到所有与该点相邻的边。

4. 较好的灵活性和扩展性:链式前向星可以灵活地添加额外信息,比如权重、流量等,并且方便扩展到更复杂的图算法中。



标签:map,存储,下标,idx,顶点,节点,号边
From: https://www.cnblogs.com/carrotbinbin1F/p/17334957.html

相关文章

  • 体验.NET与文件存储服务MinIO
    对象文件存储服务(OSS)主要用于存储零散的文件,和直接存储到本地文件系统中相比,有以下的几个优势:跨服务器可用兼容AmazonS3API横向扩容高可用支持加密MinIO就是一个高性能的文件服务,我们使用.NET来操作一下。部署MinIO最简单的办法,就是在Docker上运行MinIO。可以使用以......
  • DAMA认证|2021年大数据存储安全如何管理?
    在大数据(Bigdata)时代,通过互联网、社交网络、物联网,人们能够及时全面地获得大信息。同时,信息自身存在形式的变化与演进,也使得作为信息载体的数据以远超人们想象的速度迅速膨胀。随着Ai、5G、IoT的兴起和发展,全球每年产生的数据以爆发的态势急速增长。数据存储是基础且关键......
  • 如何实现多存储文件传输,镭速提供多存储文件传输解决方案
    目前的文件传输系统中,大多数采用的文件传输系统只支持单个的存储。随着科技的发展,存储的类型越来越多,构建的越来越复杂,业务要求越来越多样化,只支持单个存储的文件传输系统是无法满足现有的需求。为实现高自由度的将不同的存储放在同一个服务器,镭速通过一种虚拟路径的方法,将不同对......
  • MySQL InnoDB存储引擎选择B+树作为索引数据结构的原因
    MySQLInnoDB存储引擎选择B+树作为索引数据结构的原因在于其特点与性能。B+树相比红黑树和B树,更适用于关系型数据库的特点,具体体现在以下几个方面:磁盘I/O效率:数据库的数据通常存储在磁盘上,磁盘I/O操作相对较慢。B+树的一个重要特点是它能减少磁盘I/O次数。B+树是一种多路平衡查......
  • MySQL InnoDB存储引擎选择B+树作为索引数据结构的原因
    MySQLInnoDB存储引擎选择B+树作为索引数据结构的原因在于其特点与性能。B+树相比红黑树和B树,更适用于关系型数据库的特点,具体体现在以下几个方面:磁盘I/O效率:数据库的数据通常存储在磁盘上,磁盘I/O操作相对较慢。B+树的一个重要特点是它能减少磁盘I/O次数。B+树是一种多路平衡查......
  • 云存储和云计算之间相比较,主要是什么关系?
    现在的IT业界对于云集计算的钟爱超过了以往的任何时候,云计算产业被认为是继大型计算机、个人计算机、互联网之后的第四次IT产业革命,IT行业进入云时代,对IT界的大小企业来说云计算就是一次炼狱。其实在某种的意义上云计算并不是一项全新的技术,是在信息化积累到一定的程度需要对于IT......
  • 【服务器数据恢复】DELL EqualLogic PS系列存储磁盘坏道导致存储不可用的数据恢复案例
    服务器数据恢复环境:DELLEqualLogicPS系列某型号存储;16块SAS硬盘组成一组RAID5;划分了4个卷,采用VMFS文件系统,存放虚拟机文件。服务器故障:存储设备中磁盘出现故障导致存储不可用,且存储设备已经过保,用户方联系到我们数据恢复中心要求恢复该存储设备中的数据数据。服务器数据恢......
  • 企业对NAS私有云存储有什么样的需求,NAS网络存储又有哪些优势与功能呢?
    在过去十年中,云计算从公有云起步,逐渐发展出私有云/专有云和混合云。所以在私有云等云技术不断发展的情况下,企业对NAS私有云存储有什么样的需求呢?NAS网络存储又有哪些优势与功能呢?NAS网络存储有以下5大优势:(1)易于扩展:根据服务器使用人数和空间及时扩展存储空间,不会影响前端用户的......
  • JDBC 调用自定义函数(常说的存储过程)的步骤
     平常说的存储过程(Procedure),严格意义上是自定义函数,所以这里以【自定义函数】为名,简称【函数(function)】。 packagecom.joyupx.jdbc;importlombok.extern.slf4j.Slf4j;importorg.junit.jupiter.api.Test;importjava.io.IOException;importjava.io.InputStream;im......
  • Pandas另存为excel的时候我想从B列开始存储,不想要A列,应该怎么处理呢?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【eric】问了一个Pandas的问题,这里拿出来给大家分享下。另存为excel的时候我想从B列开始存储,不想要A列,应该怎么处理呢?另存为excel的时候我想从B列开始存储,不想要A列,应该怎么处理呢?我看start_col=1的时候,A列还是存在,只不过......