C++STL中的BFS图遍历

BFS graph traversal in C++ STL

本文关键字:遍历 BFS 中的 C++STL      更新时间:2023-10-16

我想用STL在C++中实现BFS图遍历。BFS不能正常工作。我看到每个人都使用队列来实现BFS。所以我自己尝试了一下,但肯定遗漏了什么。我的实现将重复项添加到队列中,从而多次遍历一些顶点。我应该使用集合而不是队列来消除重复项吗??

class Graph {
public:
    Graph(int n): numOfVert {n}{
        adjacencyLists.resize(n);
    }
    void addEdge(std::pair<int,int> p);
    void BFS(int start);
private:
    int numOfVert;
    std::vector<std::list<int>> adjacencyLists;
};
void Graph::BFS(int start){
    std::cout << "BFS: ";
    std::vector<int> visited(numOfVert, 0);
    std::queue<int> q; q.push(start);
    while(!q.empty()){
        int curr = q.front(); q.pop();
        std::cout << curr << " ";
        visited.at(curr) = 1;
        for(const auto x: adjacencyLists.at(curr)){
            if(visited.at(x) == 0) q.push(x);
        }
    }
    std::cout << "n";
}
int main(){
    Graph g(4);
    std::set<std::pair<int,int>> E {{0,1}, {1,2}, {1,3}, {2,3}};
    for(auto& x: E) g.addEdge(x);
    g.print();
    g.BFS(0);
}

当您在队列上推送节点时,您不再希望它有资格进行另一次推送,即只访问每个节点一次。因此,您标记了访问的每个推送元素。你可以添加一个简单的lambda来解决这个问题。

std::queue<int> q; 
auto push_and_visit= [&q, &visited](int node){ 
                                   q.push(node); visited[node] = 1; };
push_and_visit(start);
while(!q.empty()){
    int curr = q.front(); q.pop();
    std::cout << curr << " ";
    for(const auto x: adjacencyLists.at(curr)){
        if(visited.at(x) == 0) push_and_visit(x);
    }
}