图是由节点(通常称为顶点)和连接这些节点的边组成的数据结构。在这个基础实现中,我们将实现一个简单的无向图,并演示几个基本操作,如添加顶点、添加边、搜索等。
对于每个顶点,存储一个列表,表示与该顶点相连的所有其他顶点。这通常可以通过哈希表或对象实现,其中键是顶点,值是与该顶点相邻的顶点列表。
优点:
- 空间复杂度与边数成正比,对于稀疏图更加空间有效。
- 可以更容易地添加或删除顶点和边。
缺点:
- 查询两个顶点之间是否存在边可能需要O(V)时间,其中V是与其中一个顶点相邻的顶点数。
创建图的基本结构
我们使用邻接列表来表示图。
class Graph {
constructor() {
this.adjacencyList = {};
}
}
添加顶点
向图中添加一个新的顶点。
Graph.prototype.addVertex = function(vertex) {
if (!this.adjacencyList[vertex]) {
this.adjacencyList[vertex] = [];
}
}
添加边
向图中添加一个无向边。
Graph.prototype.addEdge = function(vertex1, vertex2) {
// 两个顶点都应该已经在图中
if (this.adjacencyList[vertex1] && this.adjacencyList[vertex2]) {
this.adjacencyList[vertex1].push(vertex2);
this.adjacencyList[vertex2].push(vertex1);
}
}
深度优先搜索
深度优先搜索 (DFS) 是一种用于遍历或搜索树或图的算法。
Graph.prototype.dfs = function(start) {
const result = [];
const visited = {};
const adjacencyList = this.adjacencyList;
(function dfs(vertex) {
if (!vertex) return;
visited[vertex] = true;
result.push(vertex);
adjacencyList[vertex].forEach(neighbor => {
if (!visited[neighbor]) {
return dfs(neighbor);
}
});
})(start);
return result;
}
广度优先搜索
广度优先搜索 (BFS) 也是一种图遍历算法,它从根节点开始并尝试访问尽可能多的节点。
Graph.prototype.bfs = function(start) {
const queue = [start];
const result = [];
const visited = {};
visited[start] = true;
while(queue.length) {
let currentVertex = queue.shift();
result.push(currentVertex);
this.adjacencyList[currentVertex].forEach(neighbor => {
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.push(neighbor);
}
});
}
return result;
}
示例
const graph = new Graph();
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
graph.addEdge("A", "B");
graph.addEdge("A", "C");
graph.addEdge("B", "D");
graph.addEdge("C", "D");
console.log(graph.dfs("A")); // 输出: ['A', 'B', 'D', 'C']
console.log(graph.bfs("A")); // 输出: ['A', 'B', 'C', 'D']