数据结构与算法: 图的顺序表示(邻接矩阵)和链表表示(邻接列表表示)
图
可以将图定义为用于连接这些顶点的顶点和边组。图可以看作是一个循环树,其中顶点(节点)在它们之间保持任何复杂的关系,而不是具有父子关系。
图的定义
图 G 可以定义为有序集 G(V, E),其中 V(G) 表示顶点集,E(G) 表示用于连接这些顶点的边集。
具有 5 个顶点(A、B、C、D、E)和 6 条边((A,B)、(B、C、C)、(C、E、D、B)、(D、A))的图形 G(V、E)、(D、B)、(D、A))如下图所示。
有向图(Directed)和无向图(Undirected)
图 可以是有向的,也可以是无向的。但是,在无向图中,边不与它们的方向相关联。无向图所示,因为它的边缘不与任何方向相连。如果顶点 A 和 B 之间存在一条边,则可以遍历顶点从 B 到 A 以及 A 到 B。
在有向图中,边形成一个有序对。边表示从某个顶点 A 到另一个顶点 B 的特定路径。节点 A 称为初始节点,而节点 B 称为终端节点。
图的术语
路径Path
路径可以定义为从初始节点 U 到达某个终端节点 V 时所遵循的节点序列。
封闭路径Closed Path
如果初始节点与终端节点相同,则路径将称为封闭路径。如果 V0=VN,则路径将为闭合路径。
简单路径Simple Path
如果图的所有节点都是不同的,但有一个异常 V0=VN,则将此类路径 P 称为闭合简单路径。
周期Cycle
循环可以定义为除第一个和最后一个顶点外没有重复边或顶点的路径。
连接图Connected Graph
连接图是 V 中每两个顶点 (u, v) 之间存在一些路径的图。连接图中没有孤立的节点。
完整图表Complete Graph
完整图是每个节点与所有其他节点连接的图。一个完整的图包含 n(n-1)/2 条边,其中 n 是图中的节点数。
加权图Weight Graph
在加权图中,每个边都分配有一些数据,例如长度或重量。边 e 的权重可以表示为 w(e),它必须是一个正 (+) 值,表示遍历边的成本。
有向图Digraph
双连图是一个有向图,其中图的每个边都与某个方向相关联,并且只能在指定方向上进行遍历。
圈Loop
与相似端点关联的边可称为循环。
相邻节点Adjacent Nodes
如果两个节点 u 和 v 通过一条边 e 连接,则 u 和 v 节点称为邻居或相邻节点。
节点的度数Degree of the
节点的度数是与该节点连接的边数。度数为 0 的节点称为独立节点。
图的表示
在本文中,我们将讨论表示图形的方法。通过图形表示,我们只是意味着用于将某些图形存储到计算机内存中的技术。
图形是由一组顶点(称为节点)和边组成的数据结构。有两种方法可以将图形存储到计算机的内存中:
- 顺序表示(或邻接矩阵表示)
- 链表表示形式(或邻接列表表示形式)
在顺序表示中,邻接矩阵用于存储图形。而在链表表示中,使用邻接列表来存储图形。
顺序表示
在顺序表示中,使用邻接矩阵来表示图形的顶点和边缘之间的映射。我们可以使用邻接矩阵来表示无向图,有向图,加权有向图和加权无向图。
如果 adj[i][j] = w,则表示从顶点 i 到顶点 j 存在一条权重为 w 的边。
如果 Vi 和 Vj 之间存在边,则无向图 G 的邻接矩阵表示中的条目 Aij 将为 1。
如果无向图 G 由 n 个顶点组成,则该图的邻接矩阵为 n x n,矩阵 A = [aij] 可以定义为
aij = 1 {如果存在从 Vi 到 Vj 的路径}
aij = 0 {否则}
这意味着,在邻接矩阵中,0 表示节点之间不存在关联,
而 1 表示两条边之间存在路径。
如果图中没有自循环,则意味着邻接矩阵的对角线条目将为 0。
现在,让我们看看无向图的邻接矩阵表示形式。
在上图中,一幅图像显示了顶点(A、B、C、D、E)之间的映射,并且此映射通过使用邻接矩阵来表示。
有向图和无向图存在不同的邻接矩阵。在有向图中,只有当有一条从 Vi 指向 Vj 的边时,条目 Aij 才会为 1。
有向图的邻接矩阵
在有向图中,边表示从一个顶点到另一个顶点的特定路径。假设存在从顶点A到另一个顶点B的路径;这意味着节点 A 是初始节点,而节点 B 是终端节点。
考虑以下有向图,并尝试构造它的邻接矩阵。
在上图中,我们可以看到没有自循环,因此相邻矩阵的对角线条目为0。
加权有向图的邻接矩阵
它类似于有向图的邻接矩阵表示,不同之处在于,这里我们必须使用与边关联的权重,而不是使用“1”表示路径的存在。图形边缘上的权重将表示为邻接矩阵的条目。我们可以借助示例来理解它。考虑下图及其邻接矩阵表示形式。在表示中,我们可以看到与边关联的权重表示为邻接矩阵中的条目。
在上图中,我们可以看到加权有向图的邻接矩阵表示与其他表示不同。这是因为,在此表示中,非零值被分配给边的实际权重所取代。
邻接矩阵更易于实现和遵循。当图形密集且许多边很大时,可以使用邻接矩阵。
虽然,使用邻接矩阵是有利的,但它会消耗更多空间。即使图形是稀疏的,矩阵仍然占用相同的空间。
链表表示
在链接表示中使用邻接列表将图形存储在计算机的内存中。它在存储方面是有效的,因为我们只需要存储边缘的值。
让我们看看无向图的邻接列表表示形式。
在上图中,我们可以看到,对于图的每个节点都有一个链接列表或邻接列表。从顶点 A 开始,有通往顶点 B 和顶点 D 的路径。这些节点链接到给定邻接列表中的节点 A。
为图中存在的每个节点维护一个邻接列表,该列表存储节点值和指向相应节点的下一个相邻节点的指针。如果遍历了所有相邻节点,则将 NULL 存储在列表最后一个节点的指针字段中。
邻接列表的长度之和等于无向图中存在的边数的两倍。
现在,考虑有向图,让我们看看该图的邻接列表表示形式。
对于有向图,邻接列表的长度之和等于图中存在的边数。
现在,考虑加权有向图,让我们看看该图的邻接列表表示形式。
对于加权有向图,每个节点都包含一个称为节点权重的额外字段。
在邻接列表中,很容易添加顶点。
由于使用了链接列表,因此还可以节省空间。
posted on 2022-04-16 09:47 Michael_chemic 阅读(673) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报