图的遍历(广度优先遍历)(深度优先遍历)

图的遍历

树代表的是“一对多”的关系,而图代表的是“多对多”的关系,我们可以将树看作是图的一种特例

图的遍历方式分为两种,分别为广度优先遍历和深度优先遍历

广度优先遍历

广度优先遍历是一种由近及远的遍历方式,从根节点出发,优先遍历距离根节点最近的节点,并一层层的向外扩张

  • BFS通常借助队列来实现,队列具有“先进先出”的性质,这与BFS的“由近即远”的思想异曲同工
  • 将遍历的起始点startvet加入队列,并开始循环
  • 在每轮循环中,弹出队首元素,并访问节点,然后将该顶点的所有邻接点加入队列的尾部
  • 循环挫折上一步操作,直到队列为空
/* 广度优先遍历 */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
vector graphBFS(GraphAdjList &graph, Vertex *startVet) {
    // 顶点遍历序列
    vector res;
    // 哈希表,用于记录已被访问过的顶点
    unordered_set visited = {startVet};
    // 队列用于实现 BFS
    queue que;
    que.push(startVet);
    // 以顶点 vet 为起点,循环直至访问完所有顶点
    while (!que.empty()) {
        Vertex *vet = que.front();
        que.pop();          // 队首顶点出队
        res.push_back(vet); // 记录访问顶点
        // 遍历该顶点的所有邻接顶点
        for (auto adjVet : graph.adjList[vet]) {
            if (visited.count(adjVet))
                continue;            // 跳过已被访问的顶点
            que.push(adjVet);        // 只入队未访问的顶点
            visited.emplace(adjVet); // 标记该顶点已被访问
        }
    }
    // 返回顶点遍历序列
    return res;
}

深度优先遍历

深度优先遍历是一种优先走到底、无路可走再回头的遍历方式

/* 深度优先遍历辅助函数 */
void dfs(GraphAdjList &graph, unordered_set &visited, vector &res, Vertex *vet) {
    res.push_back(vet);   // 记录访问顶点
    visited.emplace(vet); // 标记该顶点已被访问
    // 遍历该顶点的所有邻接顶点
    for (Vertex *adjVet : graph.adjList[vet]) {
        if (visited.count(adjVet))
            continue; // 跳过已被访问的顶点
        // 递归访问邻接顶点
        dfs(graph, visited, res, adjVet);
    }
}

/* 深度优先遍历 */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
vector graphDFS(GraphAdjList &graph, Vertex *startVet) {
    // 顶点遍历序列
    vector res;
    // 哈希表,用于记录已被访问过的顶点
    unordered_set visited;
    dfs(graph, visited, res, startVet);
    return res;
}

你可能感兴趣的:(数据结构,深度优先,宽度优先,算法)