JavaScript 数据结构系列目录
文章目录
一、图的概述
首先让我们来看看图长啥样。
(图片来源于网络,侵权必删)
在计算机科学里,图是由一些节点(或顶点) 组成的 集合。而这些顶点通过一系列的边来链接。
任何社交网络,例如一个人所拥有的人脉都可以用图来表示。
二、图的相关术语
相邻顶点 :由一条边来连接在一起的顶点称为相邻顶点。
如上图里,a 与 b是相邻的,a 与 c 是相邻的,但 a 与 d 不是相邻的。
度 :一个顶点度是其相邻顶点的数量。
如上图里 a 与两个顶点相邻,那么其度为2。b 与三个顶点相邻,那么其度为3。
路径 :路径是顶点 v1,v2,…,vk的一个连续序列,其中 vi 和 vi + 1 是相邻的。
如上图所示,a,b,d,f 是一条简单的路径。
环 :如果路径的最后一个顶点能重新回到该路径的第一个顶点,那么该路径称之为环。
如果图中不存在环,那么该图是无环的。如果图中每两个顶点都存在路径,则该图是联通的。
1、有向图与无向图
图可以是无向的(边没有方向,即无向图),也可以是有向的(即有向图,有向图的边至少有一个方向)。
我们可以观察一下下图。
在这个图里我们可以看见,A 与 E点是双向链接的,则证明此图是强连通的。
例如,A 与 E 是强连通的,A 与 B不是强连通的。
2、加权图与未加权图
图片也还可以是未加权的(上面的两个图都是未加权的)或是加权的(加权图的边被赋予了值)。
三、图的表示
从数据结构的角度来说,我们有很多方式来表示,在所有的表示法中,不存在绝对正确的方法。
图的正确表示法取决于待解决的问题和其类型。
1、邻接矩阵
图最常见的表示方法就是邻接矩阵。
这里我们可以参考下图。
不是强连通的图如果用邻接矩阵来表示,则矩阵中会有很多0,这意味着我们浪费了计算机的存储空间来表示根本不存在的边。
同样的,如果图中的顶点数里改变了,那么我们也不太好修改矩阵(二维数组不太灵活)。
2、邻接表
我们也可以使用 邻接表 来表示图。
邻接表由图中每个顶点的相邻点列表组成。
而这种数据结构存在好几种的实现方法。
我们可以用数组,链表,字典或是散列表来实现。
下图展示了邻接表的数据结构。
四、创建图类
照例声明一个类。
class Graph {
constructor(isDirected = false) {
this.isDirected =isDirected;
this.vertices = [];
this.adjList = new Dictionary();
}
}
在 Graph 类的构造函数里,我们声明了三个变量。
isDirected 变量来表示图是否存在向,默认情况下图是无向的。
vertices 变量用来存储图中所欲顶点的名字。
adjList 字典(该字典我们在本系列第七篇中以实现)用来存储邻接表。
adjList 字典会使用顶点的名字作为键,邻接顶点列表作为值。
声明完后,我们来实现这么几个方法。
1、addVertex 方法
addVertex(v) {
if ( this.vertices.includes(v) ) return;
this.vertices.push(v);
this.adjList.set(v,[]);
}
该方法用于创建一个顶点。
如果该值存在于图中,那么则不进行任何操作。‘
如果不存在,那么我们将这个值放入图中,并且为其对应的字典值设为一个空数组。
2、addEdge 方法
addEdge(v,w) {
if ( !this.adjList.get(v) ) this.addVertex(v);
if ( !this.adjList.get(w) ) this.addVertex(w);
this