什么是图?

图是网络结构的抽象模型,是一组由边连接的节点。图可以表示任何二元关系,比如道路、航班等。在 JavaScript 中没有图,但是可以通过 Object Array 来构建图。

图的常用操作

  • 深度优先遍历
  • 广度优先遍历

图的表示法

  • 邻接矩阵
  • 邻接表
  • 关联矩阵

图 - 图1

邻接矩阵:

A B C D E
A 0 1 0 0 0
** 0 0 1 1 0
C 0 0 0 0 1
D 1 0 0 0 0
E 0 0 0 1 0

邻接表:
并非仅限于通过数组表示,其他形式也可以。

  1. {
  2. "A": ["B"],
  3. "B": ["C", "D"],
  4. "C": ["E"],
  5. "D": ["A"],
  6. "E": ["D"]
  7. }

图的深度/广度优先遍历

  • 深度优先遍历
  • 尽可能深的搜索图的分支

口诀:

  1. 先访问根节点
  2. 对根节点的没访问过的相邻节点挨个进行深度优先遍历(因为相邻节点可能也会指向当前节点)
  1. const graph = {
  2. A: ['B'],
  3. B: ['C', 'D'],
  4. C: ['E'],
  5. D: ['A'],
  6. E: ['D'],
  7. };
  8. const visited = new Set();
  9. const dfs = (n) => {
  10. console.log(n);
  11. visited.add(n);
  12. graph[n].forEach((item) => {
  13. if (!visited.has(item)) {
  14. dfs(item);
  15. }
  16. });
  17. };
  18. dfs('A'); // A B C E D

广度优先遍历:
先访问离根节点最新的节点。

口诀:

  1. 新建一个队列,把根节点入队
  2. 把队头出队并访问
  3. 把队头的没有访问过的相邻节点入队
  4. 重复第2、3步直到队列为空
  1. const graph = {
  2. A: ['B'],
  3. B: ['C', 'D'],
  4. C: ['E'],
  5. D: ['A'],
  6. E: ['D'],
  7. };
  8. const bfs = (head) => {
  9. const visited = new Set();
  10. visited.add(head);
  11. const q = [head];
  12. while (q.length) {
  13. const n = q.shift();
  14. console.log(n);
  15. graph[n].forEach((item) => {
  16. if (!visited.has(item)) {
  17. q.push(item);
  18. visited.add(item);
  19. }
  20. });
  21. }
  22. };
  23. bfs('A'); // A B C D E