引入图的概念
图是一种非线性数据结构,它由一系列顶点(也称为节点)和连接这些顶点的边组成。图可以分为有向图和无向图。在有向图中,边具有方向性;而在无向图中,边没有方向性。
图的表示方法通常有两种:邻接矩阵和邻接表。邻接矩阵使用二维数组来表示,而邻接表使用链表或数组列表来表示。选择哪种表示方法取决于具体的应用场景和需求。
邻接矩阵表示法
邻接矩阵是一种通过二维数组来表示图的方法。对于一个有n个顶点的图,邻接矩阵是一个n×n的二维数组。如果两个顶点之间存在边,则对应的数组元素为1或权重值;否则为0。
创建邻接矩阵
function createAdjacencyMatrix(numVertices) { const matrix = new Array(numVertices); for (let i = 0; i < numVertices; i++) { matrix[i] = new Array(numVertices).fill(0); } return matrix; }
添加边
function addEdge(matrix, vertex1, vertex2, weight = 1) { if (vertex1 >= 0 && vertex1 < matrix.length && vertex2 >= 0 && vertex2 < matrix.length) { matrix[vertex1][vertex2] = weight; // 如果是无向图,还需要添加反向边 matrix[vertex2][vertex1] = weight; } }
查找边
function hasEdge(matrix, vertex1, vertex2) { return matrix[vertex1][vertex2] !== 0; }
邻接表表示法
邻接表是一种通过数组或链表来表示图的方法。每个顶点都有一个列表,列表中的元素是与该顶点相邻的顶点。这种表示方法特别适合稀疏图。
创建邻接表
function createAdjacencyList(numVertices) { return new Array(numVertices).fill(null).map(() => []); }
添加边
function addEdgeToList(list, vertex1, vertex2, weight = 1) { list[vertex1].push({ vertex: vertex2, weight }); // 如果是无向图,还需要添加反向边 list[vertex2].push({ vertex: vertex1, weight }); }
查找边
-- -------------------- ---- ------- -------- ------------------- -------- -------- - ----- --------- - -------------- --- ------ -------- -- ---------- - -- ---------------- --- -------- - ------ ----- - - ------ ------ -
深度优先搜索(DFS)
深度优先搜索是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
实现DFS
-- -------------------- ---- ------- -------- ---------- ------------ ------- - --- ------ - ------------------------- ------------------------- -- ------ ------------------------- ------- -- - -- ---------------------- - ---------- ------- --------- - --- -
广度优先搜索(BFS)
广度优先搜索是一种用于遍历或搜索树或图的算法。它从根节点开始,沿着树的宽度遍历树的节点,如果所有节点均被访问,则算法终止。广度优先搜索是完成这种任务的最佳方法之一。
实现BFS
-- -------------------- ---- ------- -------- ---------- ------------ - ----- ----- - -------------- ----- ------- - --- ------------------- ----- ------------- - -- - ----- ------------- - -------------- --------------------------- -- ------ ------------------------------- ------ -- -- - -- ---------------------- - -------------------- ------------------- - --- - -
最短路径算法
最短路径问题是指在加权图中找到两个节点之间的最短路径的问题。常见的最短路径算法有Dijkstra算法和Bellman-Ford算法。
Dijkstra算法
Dijkstra算法是一种用于寻找给定起点的最短路径的贪心算法。
实现Dijkstra算法
-- -------------------- ---- ------- -------- --------------- ------------ - ----- --------- - --- ----- ---------------- - --- -- ----- --- ------ ------ -- ------ - ----------------- - --------- - ---------------------- - -- -- --- ----- ------------------------------- - --- ------------- - ----- --- ------ ------ -- ----------------------- - -- -------------- --- ---- -- ----------------- - ------------------------- - ------------- - ------- - - ----- --------- - --------------------- --- ------ - ------- ------ - -- ---------- - ----- ---------------- - ------------------------ - ------- -- ----------------- - ------------------ - ----------------- - ----------------- ------------------------ - -------------- - - ------ ------------------------- - ------ - ---------- ---------------- -- -
Bellman-Ford算法
Bellman-Ford算法是一种用于寻找最短路径的动态规划算法,能够处理负权重边。
实现Bellman-Ford算法
-- -------------------- ---- ------- -------- ------------------ ------------ - ----- --------- - --- ----- ---------------- - --- -- ----- --- ------ ------ -- ------ - ----------------- - --------- - ---------------------- - -- -- ---------- --- ---- - - -- - - ------------------------- - -- ---- - --- ------ ------------- -- ------ - ----- --------- - --------------------- --- ------ - ------- ------ - -- ---------- - ----- ---------------- - ------------------------ - ------- -- ----------------- - ------------------ - ----------------- - ----------------- ------------------------ - -------------- - - - - -- --------- --- ------ ------------- -- ------ - ----- --------- - --------------------- --- ------ - ------- ------ - -- ---------- - ----- ---------------- - ------------------------ - ------- -- ----------------- - ------------------ - ----- --- ------------ -------- - --------------- -------- - - - ------ - ---------- ---------------- -- -
拓扑排序
拓扑排序是对有向无环图(DAG)进行排序的一种算法,它使得对于每一条有向边(u,v),u都排在v的前面。拓扑排序不是唯一的,不同的算法可能会产生不同的结果。
实现拓扑排序
-- -------------------- ---- ------- -------- ---------------------- - ----- -------- - --- ----- ----- - --- ----- ------ - --- -- ----- --- ------ ------ -- ------ - ---------------- - -- - -- --------- --- ------ ------ -- ------ - ------------------------ ------- -------- -- -- - --------------------- --- - -- ------------ --- ------ ------ -- --------- - -- ----------------- --- -- - ------------------- - - -- ------ ----- ------------- - -- - ----- ------------- - -------------- --------------------------- ------------------------------- ------- -------- -- -- - --------------------- -- ------------------- --- -- - --------------------- - --- - -- ------------ -- -------------- --- -------------------------- - ----- --- ------------ -------- - -------- - ------ ------- -
总结
本章详细介绍了图的基本概念、表示方法、遍历算法和最短路径算法。理解这些基本知识有助于我们更好地利用图来解决实际问题。接下来我们将继续深入探讨更多图相关的算法和应用。