使用C ++实现BFS

时间:2015-05-31 03:19:49

标签: c++ c++11 breadth-first-search

我正在尝试用C ++实现BFS,这是代码。

#include <iostream>
#include <list>
#include <string>
#include <limits>
#include <map>

int infinity=std::numeric_limits<int>::max();


struct Node{
        int value;
        int distance;
        std::string color;

        Node(int val):
        value(val),
        distance(infinity),
        color("white")
        {}
};

//using AdjList = std::map<Node*,std::list<Node*>>;
typedef std::map<Node*,std::list<Node*>> AdjList;
AdjList create_graph()
{
    Node* n1 = new Node(1);
    Node* n2 = new Node(2);
    Node* n3 = new Node(3);
    Node* n4 = new Node(4);
    Node* n5 = new Node(5);
    Node* n6 = new Node(6);
    Node* n7 = new Node(7);
    Node* n8 = new Node(8);

    AdjList m;
    m[n1] = {n2, n5};
    m[n2] = {n1, n6};
    m[n3] = {n4, n6, n7};
    m[n4] = {n3, n7, n8};
    m[n5] = {n1};
    m[n6] = {n2, n3, n7};
    m[n7] = {n3, n4, n6, n8};
    m[n8] = {n4, n7};
    return m;
}


void bfs(const AdjList& m, Node* n1)
{
    std::list<Node*> queue;
    queue.push_back(n1);
    unsigned count = 0;

    while (!queue.empty())
    {
        auto n = queue.front();
        std::cout << n->value << std::endl;
        queue.pop_front();
        std::cout << *(m[n].begin()) << std::endl;
        for(auto it = m[n].begin(); it != m[n].end(); ++it)
        {
            if ((*it)->color != "black")
                queue.push_back(*it);
        }

        n->color = "black";
        n->distance = count;
        ++count;
    }
}

尝试使用gcc编译时,收到以下错误消息。

bfs.cpp: In function ‘void bfs(const AdjList&, Node*)’:
bfs.cpp:59:27: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
         std::cout << *(m[n].begin()) << std::endl;
                           ^
bfs.cpp:60:20: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
   for(auto it = m[n].begin(); it != m[n].end(); ++it)
                    ^
bfs.cpp:60:40: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
   for(auto it = m[n].begin(); it != m[n].end(); ++it)

我不确定是什么问题。请指出错误。

2 个答案:

答案 0 :(得分:3)

std::map::operator[]是非const的,因为它会在需要时插入元素:

int main()
{
    std::map<std::string, std::string> m;
    m["new element"] = "1";
}

问题是mconst AdjList&,你不能在其上调用非const成员函数。您可以改为使用std::map::find()

auto itor = m.find(n);
if (itor != m.end())
    std::cout << *(m->second.begin()) << std::endl;

答案 1 :(得分:1)

两个C ++ 11功能将使您的生活更轻松

  1. 地图的at() const函数,类似于[],但如果没有关键字则抛出out of range异常,而不是向地图添加新项目

  2. 容器上的for循环

  3. 所以:

    for (auto it : m.at(n))  {
      if (it->color != "black")
      queue.push_back(it);
    }