JavaScript数据结构之图

JavaScript数据结构之图图的相关术语图是网络结构的抽象模型。图是一组由边连接的节点(或顶点)。学习图是重要的,因为任何二元关系都可以用图来表示。任何社交网络,例如Facebook、Twitter和Google plus,都可以用图来表示。解一下图的一些术语:由一条边连接在一起的顶点称为相邻顶点。比如,A和B是相邻的,A和D是相邻的,A和C是相邻的,A和E不是相邻的。一个顶点的...
摘要由CSDN通过智能技术生成

JavaScript数据结构之图

图的相关术语

图是网络结构的抽象模型。图是一组由边连接的节点(或顶点)。学习图是重要的,因为任何二元关系都可以用图来表示。
任何社交网络,例如Facebook、Twitter和Google plus,都可以用图来表示。

在这里插入图片描述
解一下图的一些术语:
由一条边连接在一起的顶点称为相邻顶点。比如,A和B是相邻的,A和D是相邻的,A和C是相邻的,A和E不是相邻的。

一个顶点的度是其相邻顶点的数量。比如,A和其他三个顶点相连接,因此,A的度为3;E和其他两个顶点相连,因此,E的度为2。

路径是顶点v 1 , v 2 ,…,v k 的一个连续序列,其中v i 和v i+1 是相邻的。以上一示意图中的图为例,其中包含路径A B E I和A C D G。

简单路径要求不包含重复的顶点。举个例子,A D G是一条简单路径。除去最后一个顶点(因为它和第一个顶点是同一个顶点),环也是一个简单路径,比如A D C A(最后一个顶点重新回到A)。

如果图中不存在环,则称该图是无环的。如果图中每两个顶点间都存在路径,则该图是连通的。

有向图和无向图

图可以是无向的(边没有方向)或是有向的(有向图)。如下图所示,有向图的边有一个方向:
在这里插入图片描述
如果图中每两个顶点间在双向上都存在路径,则该图是强连通的。例如,C和D是强连通的,而A和B不是强连通的。

图还可以是未加权的(目前为止我们看到的图都是未加权的)或是加权的。如下图所示,加权图的边被赋予了权值:
在这里插入图片描述
可以使用图来解决计算机科学世界中的很多问题,比如搜索图中的一个特定顶点或搜索一条特定边,寻找图中的一条路径(从一个顶点到另一个顶点),寻找两个顶点之间的最短路径,以及环检测。

图的表示

从数据结构的角度来说,有多种方式来表示图。在所有的表示法中,不存在绝对正确的方式。图的正确表示法取决于待解决的问题和图的类型。

邻接矩阵

图最常见的实现是邻接矩阵。每个节点都和一个整数相关联,该整数将作为数组的索引。用一个二维数组来表示顶点之间的连接。如果索引为i的节点和索引为j的节点相邻,则array[i][j]=== 1,否则array[i][j] === 0,如下图所示:
在这里插入图片描述
不是强连通的图(稀疏图)如果用邻接矩阵来表示,则矩阵中将会有很多0,这意味着浪费了计算机存储空间来表示根本不存在的边。

例如,找给定顶点的相邻顶点,即使该顶点只有一个相邻顶点,我们也不得不迭代一整行。邻接矩阵表示法不够好的另一个理由是,图中顶点的数量可能会改变,而2维数组不太灵活。

邻接表

邻接表的动态数据结构也可以用来表示图。邻接表由图中每个顶点的相邻顶
点列表所组成。存在好几种方式来表示这种数据结构。可以用列表(数组)、链表,甚至是散列表或是字典来表示相邻顶点列表。下面的示意图展示了邻接表数据结构。
在这里插入图片描述
尽管邻接表可能对大多数问题来说都是更好的选择,但以上两种表示法都很有用,且它们有着不同的性质(例如,要找出顶点v和w是否相邻,使用邻接矩阵会比较快)。

关联矩阵

用关联矩阵来表示图。在关联矩阵中,矩阵的行表示顶点,列表示边。如下图所
示,使用二维数组来表示两者之间的连通性,如果顶点v是边e的入射点,则array[v][e] === 1;否则,array[v][e] === 0。
在这里插入图片描述
关联矩阵通常用于边的数量比顶点多的情况下,以节省空间和内存。

创建图类

声明类的骨架:

function Graph() {
   
	var vertices = []; //{1}
	var adjList = new Dictionary(); //{2}
}

使用一个数组来存储图中所有顶点的名字(行 {1} ),以及一个字典来存储邻接表(行 {2} )。字典将会使用顶点的名字作为键,邻接顶点列表作为值。 vertices
数组和 adjList 字典两者都是 Graph 类的私有属性。
实现两个方法:一个用来向图中添加一个新的顶点(因为图实例化后是空的),另外一个方法用来添加顶点之间的边

实现 addVertex 方法:

this.addVertex = function(v){
   
	vertices.push(v); //{3}
	adjList.set(v, []); //{4}
};

这个方法接受顶点 v 作为参数。我们将该顶点添加到顶点列表中(行 {3} ),并且在邻接表中,设置顶点 v 作为键对应的字典值为一个空数组(行 {4} )。

实现 addEdge 方法:

this.addEdge = function(v, w){
   
	adjList.get(v).push(w); //{5}
	adjList.get(w).push(v); //{6}
};

这个方法接受两个顶点作为参数。首先,通过将 w 加入到 v 的邻接表中,我们添加了一条自顶点 v 到顶点 w 的边。如果想实现一个有向图,则行 {5} 就足够了。
如果是无向图,需要添加一条自 w 向 v 的边(行 {6} )。

注意:只是往数组里新增元素,因为数组已经在行 {4} 被初始化了。

测试这段代码:

var graph = new Graph();
var myVertices = ['A','B','C','D','E','F','G','H','I']; //{7}
for (var i=0; i<myVertices.length; i++){
    //{8}
	graph.addVertex(myVertices[i]);
}
graph.addEdge('A', 'B'); //{9}
graph.addEdge('A', 'C');
graph.addEdge('A', 'D')
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值