这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
创建图
之前的系列文章,我们已经了解到了图是什么,接下来,我们一起来看看图的创建。
- 按照惯例,首先声明图类的骨架,我们采用邻接表来实现
function Graph() {
// 顶点列表
let vertices = [];
// 字典,用来存储邻接表
let adjList = new Dictionary();
}
在上述我们创建的类中,我们使用一个数组来存储图中所有顶点的名字
,使用一个字典来存储邻接表
。而字典将会使用顶点的名字作为键,邻接顶点列表作为值
。
- 接下来,我们在创建的类中实现两个方法:
addVertex(v)
: 用来向图中添加一个新的顶点。addEdge(v, w)
: 用来添加顶点之间的边。
function Graph() {
let vertices = [];
let adjList = new Dictionary();
// 方法
this.addVertex = function (v) {
// 接受顶点作为参数,将该顶点添加到顶点列表中,并在邻接表中设置该顶点作为键对应的字典值为一个空数组
vertices.push(v);
adjList.set(v, [])
}
// 该方法接收两个顶点作为参数
this.addEdge = function (v, w) {
// 首先,通过将w加入到v的邻接表中,我们添加了一条自顶点v到顶点w的边。
adjList.get(v).push(w);
// 由于我们做的是无向图,所以还需要添加一条自w向v的边
adjList.get(w).push(v)
}
// 便于输出观察实现如下的toString方法
this.toString = function () {
let str = '';
// 首先迭代顶点数组,将顶点的名字加入到字符串中
for (let i = 0; i < vertices.length; i++) {
str += `${vertices[i]} -> `
// 然后,取该顶点的邻接表,并进行迭代,同样将迭代结果加入字符串中,
let neighbors = adjList.get(vertices[i]);
for (let j = 0; j < neighbors.length; j++) {
str += `${neighbors[j]} `
}
// 迭代完成后末尾加换行符,用于将每个顶点和它的邻接表在一行显示,最终得到一个漂亮的邻接表类型的图
str += '\n'
}
return str
}
}
验证
基于上述两个方法,我们已经简单的基本实现了一个图类,那么接下来我们来验证以下:
// 首先我们实例化一个图
let graph = new Graph();
// 循环将下面的顶点添加到实例化的图中
let myVertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
let len = myVertices.length;
for (let i = 0; i < len; i++) {
graph.addVertex(myVertices[i])
}
// 接下来,我们添加边, 随意添加
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('E', 'I');
// 输出结果:
console.log(graph.toString())