返回首页返回书籍《Hello 算法》
目录

目录 · CONTENTS

  1. 01序
  2. 02前言
  3. 03关于本书
  4. 04如何使用本书
  5. 05小结
  6. 06初识算法
  7. 07算法无处不在
  8. 08算法是什么
  9. 09小结
  10. 10复杂度分析
  11. 11算法效率评估
  12. 12迭代与递归
  13. 13时间复杂度
  14. 14空间复杂度
  15. 15小结
  16. 16练习
  17. 17数据结构
  18. 18数据结构分类
  19. 19基本数据类型
  20. 20数字编码
  21. 21字符编码
  22. 22小结
  23. 23练习
  24. 24数组与链表
  25. 25数组
  26. 26链表
  27. 27列表
  28. 28内存与缓存
  29. 29小结
  30. 30练习
  31. 31栈与队列
  32. 32栈
  33. 33队列
  34. 34双向队列
  35. 35小结
  36. 36练习
  37. 37哈希表
  38. 38哈希表
  39. 39哈希冲突
  40. 40哈希算法
  41. 41小结
  42. 42练习
  43. 43树
  44. 44二叉树
  45. 45二叉树遍历
  46. 46二叉树数组表示
  47. 47二叉搜索树
  48. 48AVL 树
  49. 49小结
  50. 50练习
  51. 51堆
  52. 52堆
  53. 53建堆操作
  54. 54Top-k 问题
  55. 55小结
  56. 56练习
  57. 57图
  58. 58图
  59. 59图的基础操作
  60. 60图的遍历
  61. 61小结
  62. 62练习
  63. 63搜索
  64. 64二分查找
  65. 65二分查找插入点
  66. 66二分查找边界
  67. 67哈希优化策略
  68. 68重识搜索算法
  69. 69小结
  70. 70练习
  71. 71排序
  72. 72排序算法
  73. 73选择排序
  74. 74冒泡排序
  75. 75插入排序
  76. 76快速排序
  77. 77归并排序
  78. 78堆排序
  79. 79桶排序
  80. 80计数排序
  81. 81基数排序
  82. 82小结
  83. 83练习
  84. 84分治
  85. 85分治算法
  86. 86分治搜索策略
  87. 87构建二叉树问题
  88. 88汉诺塔问题
  89. 89小结
  90. 90练习
  91. 91回溯
  92. 92回溯算法
  93. 93全排列问题
  94. 94子集和问题
  95. 95n 皇后问题
  96. 96小结
  97. 97练习
  98. 98动态规划
  99. 99初探动态规划
  100. 100动态规划问题特性
  101. 101动态规划解题思路
  102. 1020-1 背包问题
  103. 103完全背包问题
  104. 104编辑距离问题
  105. 105小结
  106. 106练习
  107. 107贪心
  108. 108贪心算法
  109. 109分数背包问题
  110. 110最大容量问题
  111. 111最大切分乘积问题
  112. 112小结
  113. 113练习
  114. 114附录
  115. 115编程环境安装
  116. 116一起参与创作
  117. 117术语表
  118. 118参考文献
  119. 119纸质书
第 62 / 119 节

第 62 节 · SECTION 62

练习

知识巩固

用两种方式表示同一张图

一个无向图有 4 个顶点 A、B、C、D,边为 A-B、A-C、B-C、C-D。

  1. 写出它的邻接表;
  2. 填写只含 0 和 1 的邻接矩阵;
  3. 如果要判断 A 和 D 是否直接相连,哪种图的表示方法只需查看一个存储条目?
  4. 如果图的顶点很多但边很少,哪种表示通常更节省空间?

参考答案

  1. 邻接表为:

    A: B, C
    B: A, C
    C: A, B, D
    D: C
    
  2. 邻接矩阵为:

    A B C D
    A 0 1 1 0
    B 1 0 1 0
    C 1 1 0 1
    D 0 0 1 0
  3. 邻接矩阵可直接查看第 A 行、第 D 列,因此很适合判断任意两点是否直接相连。

  4. 顶点很多但边很少时,邻接表只记录实际存在的边,通常比为每一对顶点都预留位置的邻接矩阵更节省空间。

广度优先与深度优先访问顺序

一个无向图的顶点为 A、B、C、D、E,边为 A-B、A-C、B-D、C-D、D-E。

从 A 出发,并规定遇到多个未访问邻接顶点时按字母顺序选择:

  1. 写出广度优先遍历(BFS)的访问顺序;
  2. 写出递归深度优先遍历(DFS)的访问顺序;
  3. 为什么两种遍历都需要记录已经访问过的顶点?

参考答案

  1. BFS 的访问顺序为 A, B, C, D, E。它先访问离 A 一条边的 B、C, 再访问更远的 D、E。

  2. DFS 的访问顺序为 A, B, D, C, E。它依次进入当前顶点的未访问邻接顶点, 因此先走过 A → B → D → C;C 没有新的邻接顶点时回到 D,再访问 E。

  3. 图中存在环,例如 A-B-D-C-A。如果不记录已访问顶点, 遍历可能反复沿环访问同一批顶点,无法正常结束。

一次 BFS 能访问整张图吗

一个无向图有顶点 A、B、C、D、E、F,边只有 A-B、B-C、D-E。

  1. 从 A 开始进行一次 BFS,可以访问哪些顶点?
  2. 根据第 1 问,这一次 BFS 是否已经访问图中的所有顶点?为什么?
  3. 若按字母顺序扫描所有顶点,每遇到一个未访问顶点就重新开始 BFS, 各次 BFS 的起点是什么?这个图被分成几个互不连通的部分(连通分量)?

参考答案

  1. 从 A 出发只能访问 A、B、C。

  2. 没有访问所有顶点。D、E 组成另一个互相连通的部分,F 是单独的顶点; 它们与 A 之间都没有路径,因此从 A 出发无法到达。

  3. 三次 BFS 的起点依次为 A、D、F,分别访问 {A, B, C}、{D, E} 和 {F}。因此这个图有 3 个连通分量。

编程练习

判断无向图中是否存在路径

给定一个含有 $n$ 个顶点的无向图,顶点编号为 $0$ 到 $n-1$。数组 edges 中的每一项 [u, v] 表示顶点 u 和 v 之间有一条无向边。

再给定起点 source 和终点 destination。请先根据 edges 建立邻接表,再使用 BFS 或 DFS 判断是否存在一条从 source 到 destination 的路径:存在则返回 true,否则返回 false。 图中可能有环,也可能不连通。

解题提示

  1. 每条无向边需要同时加入两个方向
  2. 图中可能有环,必须记录已经访问过的节点
  3. 从 source 出发,遇到 destination 返回 true,遍历结束仍未遇到则返回 false

LeetCode