Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BFS graph traversal in C++ STL

I wanted to implement BFS graph traversal in C++ using STL. BFS doesn't work as it should. I saw that everyone uses queue to implement BFS. So I tried it myself but I must be missing sth. My implementation adds duplicates to the queue and thus traverse some vertices multiple times. Should I use set instead of queue to get rid of duplicates??

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);
}

1 Answers

When you push the node on the queue, you no longer want it eligible for another push, i.e. visiting each node only once. Hence you mark every pushed element visited. You could add a simple lambda to solve this.

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);
    }
}
like image 195
Captain Giraffe Avatar answered Nov 29 '25 01:11

Captain Giraffe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!