【JavaScript数据结构】图之邻接列表

68 阅读2分钟

图是由节点(通常称为顶点)和连接这些节点的边组成的数据结构。在这个基础实现中,我们将实现一个简单的无向图,并演示几个基本操作,如添加顶点、添加边、搜索等。

对于每个顶点,存储一个列表,表示与该顶点相连的所有其他顶点。这通常可以通过哈希表或对象实现,其中键是顶点,值是与该顶点相邻的顶点列表。

优点:

  • 空间复杂度与边数成正比,对于稀疏图更加空间有效。
  • 可以更容易地添加或删除顶点和边。

缺点:

  • 查询两个顶点之间是否存在边可能需要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']