❤️图的遍历❤️

广度优先搜索

'广搜':以v为起始点,由近至远依次访问和v路径想通且路径长度为1,2,...的顶点
'广搜'是一种分层的查找过程
为了实现逐层的访问,算法必须借助一个'辅助队列'
(vis 数组和队列)
算法过程可以看做是图上'火苗传播的过程':最开始只有起点着火了,在每一时刻,有火的节点都向它相邻的所有节点传播火苗。

时间复杂度 O(n+m) 空间复杂度 O(n)

void bfs(int u) {
  while (!Q.empty()) Q.pop();
  Q.push(u);
  vis[u] = 1;
  d[u] = 0;
  p[u] = -1;
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    for (int i = head[u]; i; i = e[i].x) {
      if (!vis[e[i].t]) {
        Q.push(e[i].t);
        vis[e[i].t] = 1;
        d[e[i].t] = d[u] + 1;
        p[e[i].t] = u;
      }
    }
  }
}
void restore(int x) {
  vector<int> res;
  for (int v = x; v != -1; v = p[v]) {
    res.push_back(v);
  }
  std::reverse(res.begin(), res.end());
  for (int i = 0; i < res.size(); ++i) printf("%d", res[i]);
  puts("");
}

广搜伪代码

bfs(s) {
  q = new queue()
  q.push(s), visited[s] = true
  while (!q.empty()) {
    u = q.pop()
    for each edge(u, v) {
      if (!visited[v]) {
        q.push(v)
        visited[v] = true
      }
    }
  }
}

深度优先搜索

所谓'深度优先',就是说每次都尝试向'更深的节点走'
DFS 最显著的特征在于其 递归调用自身 。同时与 BFS 类似,DFS 会对其访问过的点打上'访问标记',
在遍历图时跳过已打过标记的点,以确保 每个点仅访问一次 
'时间复杂度' O(n+m)

'空间复杂度' O(n)
其中 n 表示点数,m表示边数,复杂度包含了栈空间,栈空间的空间复杂度是 O(n)

时间复杂度 O(n+m) 空间复杂度 O(n)

void dfs(int u) {
  vis[u] = 1;
  for (int i = head[u]; i; i = e[i].x) {
    if (!vis[e[i].t]) {
      dfs(v);
    }
  }
}
posted @ 2020-07-10 15:55  xiaoff  阅读(144)  评论(0编辑  收藏  举报