什么是”图”?
图是一种非常重要,且跟现实息息相关的数据结构,它是网络结构的抽象模型。
举个非常常见的例子:
我们每天在使用百度、高德地图进行导航时,城市的地图就是一种图的结构。
我们使用QQ、微信、Twitter、Facebook等社交软件,我们的好友关系网也是一种图的结构。
不仅如此,我们还可以使用图来表示道路、航班以及通信。

图的相关术语
一个图由 G = (V,E)组成。
顶点:
图最基本的单元,也就是图中的节点。
边:
顶点之间的关联关系,被称为边。
相邻顶点:
由一条边连接在一起的顶点,被称为相邻顶点。
度:
一个顶点包含的相邻顶点的数量,被称为度。
权重和带权图:
有些图中,每一条边并不是完全等同的。如在地铁线路组成的图中,A站到B站的距离是3km,B站到C站的距离是5km,则该数值便是图的权重,而这种图,则被称为带权图。

有向图:
如果图中节点之间的边线是单向的,则被称为有向图。

无向图:
如果图中节点之间的边线是双向的,或者没有一个明确的指向,则被称为无向图。

常用代码实现图的几种方法
邻接矩阵
图最常见的实现是邻接矩阵,也就是使用二维数组,表达各个顶点之间的关联关系。

如上图所示,顶点1到顶点2之间有边关联,则矩阵中的元素[0][1]的值为1;顶点3到顶点1没有关联,则矩阵[2][0]的值为0。
图上的邻接矩阵的代码表示:
1 2 3 4 5 6 7 8 9 10 11
| let graphMatrix = [ [ 0,1,1 ], [ 0,0,0 ], [ 0,1,0 ] ]
|
邻接表
邻接矩阵虽然能表示图结构,但是占用了太多的空间。而邻接表,是图结构的另外一种表示函数。邻接表由图中每个顶点的相邻顶 点列表所组成,可以使用列表(数组)、链表,甚至是散列表或是字典来表示相邻顶点列表。

代码实现
这里以邻接表为例,实现一个图(Graph)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| import Dictionary from "../Dictionary/app.js";
export default class Graph { constructor(isDirected = false) { this.isDirected = isDirected; this.vertices = []; this.adjList = new Dictionary(); }
addVertex(v) { if (!this.vertices.includes(v)) { this.vertices.push(v); this.adjList.set(v, []); } }
addEdge(a, b) { if (!this.adjList.get(a)) { this.addVertex(a); } if (!this.adjList.get(b)) { this.addVertex(b); } this.adjList.get(a).push(b); if (this.isDirected !== true) { this.adjList.get(b).push(a); } }
getVertices() { return this.vertices; }
getAdjList() { return this.adjList; }
toString() { let s = ""; for (let i = 0; i < this.vertices.length; i++) { s += `${this.vertices[i]} -> `; const neighbors = this.adjList.get(this.vertices[i]); for (let j = 0; j < neighbors.length; j++) { s += `${neighbors[j]} `; } s += "\n"; } return s;
} }
|
后记
笔记中部分图片来自公众号:程序员小灰