广度优先搜索中的c ++迭代器和指针使用

Posted

技术标签:

【中文标题】广度优先搜索中的c ++迭代器和指针使用【英文标题】:c++ iterator and pointer usage in breadth first search 【发布时间】:2015-01-06 13:49:34 【问题描述】:

当使用更大的数组维度时,我将程序的终止隔离为始终在二维顶点数组的广度优先搜索期间:

声明了我的 Vertex 类

    class Vertex                                                   
public:
    int i, j; 
    std::set<Vertex*> adj; //references to adjacent vertices (max of 4)

    //used in solving maze
    bool visited; 
    std::list<Vertex> path; //stores path from start vertex to this vertex

    Vertex();
    ~Vertex();
    //end constructors

    void setPos(int row, int col);

    /** for iterators */
    typedef std::set<Vertex*>::iterator iterator;
    iterator begin();
    iterator end();

;//END class Vertex

在这个函数中,我有这个小节来执行 BFS:

void solveMaze(string folder, Vertex arr[][MAZE_WIDTH])
    //<randomly generate begin and end positions in maze>
    //<ensure all vertices are marked unvisited>

/* BFS */
list< Vertex > shortestPath; //shortest path from start to end
queue<Vertex*> q; //store visited vertices with one or more unvisited adjacent vertices while searching graph

arr[ begini ][ beginj ].visited = true; //mark start vertex as visited, as the search will begin here
arr[ begini ][ beginj ].path.push_back( arr[ begini ][ beginj ] ); //all paths begin at start vertex
q.push( &arr[begini][beginj] );

//explore all vertices in maze
while( !q.empty() ) 
    Vertex* cur = q.front(); //next vertex to backtrack
    q.pop();

    //for all vertices adjacent of cur
    Vertex::iterator it; //thanks to typedef
    for(it = (cur->begin()); it != (cur->end()); it++)
        //if adjacent vertex has not been visited
        if( !(*it)->visited ) 
             (*it)->visited = true; //mark vertex visited
             (*it)->path = cur->path; //save directory from start vertex..
             cout << "1\n";
             ((*it)->path).push_back( **it ); //..to this vertex     i think this line is main problem
             cout << "2\n";
             q.push( &arr[ ((*it)->i) ][ ((*it)->j) ]); //current path continues, so store vertex to backtrack later
        
    

    //path to end found, so store it if it's shortest found
    if( (cur->i) == endi && (cur->j) == endj )
        if( shortestPath.empty() )
            shortestPath = ( cur->path );
        else if( (cur->path).size() < shortestPath.size() )
            shortestPath = cur->path;
    

//end while( !q.empty() )

cout << "    -finished breadth first searching\n";
...

所以在 BFS 期间,1 2 1 2 ... 重复打印,但速度越来越慢,直到最后 1 打印出来,然后它以如下错误终止:

...
1
2
1
2
1

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
make: *** [makeExec] Error 3

所以我怀疑这是我在使用指针/迭代器等方面做错了,就像我在 while 循环上方的行中“((*it)->path).push_back(**it);”因为 1 最后打印然后它终止,但它只发生在使用更大的数组维度时。

有人可以帮我弄清楚发生了什么吗?

【问题讨论】:

在多大的数组大小时会遇到问题?你有没有检查过你是否内存不足?由于path 按值存储Vertex,我预计内存使用量会随着您增加顶点数量和它们之间的连接数而迅速爆炸。 向量通常比列表快。 【参考方案1】:

变化

std::list<Vertex> path; //stores path from start vertex to this vertex

std::list<Vertex*> path; //stores path from start vertex to this vertex

工作得很好。应该知道我浪费的资源,谢谢@uesp!

【讨论】:

以上是关于广度优先搜索中的c ++迭代器和指针使用的主要内容,如果未能解决你的问题,请参考以下文章

3.4 迭代器

迭代器的解释

C++map和set

C++map和set

C#中的枚举器和迭代器

golang中的那些坑之迭代器中的指针使用